Pętla przez pliki z wyłączeniem katalogów

11

Potrzebuję skryptu, aby zrobić coś z każdym plikiem w bieżącym katalogu, z wyłączeniem podkatalogów.

Na przykład w bieżącej ścieżce znajduje się 5 plików, ale 1 z nich to folder (podkatalog). Mój skrypt powinien aktywować polecenie podane jako argumenty podczas uruchamiania tego skryptu. To znaczy „skrypt bash wc -w” powinien podawać liczbę słów dla każdego pliku w bieżącym katalogu, ale nie dla żadnego z folderów, aby dane wyjściowe nigdy nie zawierały żadnych wierszy „/ sub / dir: Is a directory”.

Mój obecny skrypt:

#!/bin/bash
dir=`pwd`
for file in $dir/*
do
    $* $file
done

Muszę tylko wykluczyć katalogi dla pętli, ale nie wiem jak.

Tõnis Piip
źródło

Odpowiedzi:

11
#!/bin/bash -

for file in "$dir"/*
do
  if [ ! -d "$file" ]; then
      "$@" "$file"
  fi
done

Zauważ, że wyklucza to także pliki typu dowiązanie symboliczne i gdzie dowiązanie symboliczne jest rozwiązywane do pliku typu katalog (co prawdopodobnie jest tym, czego chcesz).

Alternatywnie (z komentarzy), sprawdź tylko pliki:

for file in "$dir"/*
do
  if [ -f "$file" ]; then
      "$@" "$file"
  fi
done
laktak
źródło
@roaima dobry pomysł!
laktak
2
Lepszy w użyciu if [ -f "$file" ]; then .... Żaden katalog nie zwróciłby nie tylko zwykłych plików, ale także gniazd i dowiązań symbolicznych.
JRFerguson 13.03.17
@JRFerguson na podstawie pytania OP Powiedziałbym, że włączenie gniazd i rur byłoby naprawdę złym pomysłem. Jeśli chodzi o dowiązania symboliczne, są one domyślnie ! -djuż uwzględnione.
roaima
Użyłem [-f $ plik] w moim ostatnim skrypcie. Zwróć uwagę na brak znaków cudzysłowu w warunku if. Niemal wszędzie, gdzie szukałem, były znaki cudzysłowu wokół $ file, ale musiałem je usunąć, aby mój skrypt działał.
Tõnis Piip
3

Oto alternatywa dla użycia pętli for, jeśli to, co musisz zrobić, jest proste (i nie wymaga ustawiania zmiennych w głównej powłoce & c).

Można korzystać findze -execi używać -maxdepth 1, aby uniknąć recursing do podkatalogu.

[ -n "$1" ] && find "$dir" -type f -mindepth 1 -maxdepth 1 -exec "$@" "{}" \;

Ma [ -n "$1" ]to na celu uniknięcie wykonywania wszystkich plików w katalogu, gdy skrypt nie przekaże żadnych argumentów.

Gregory Nisbet
źródło
2

W zsh możesz używać kwalifikatorów glob, aby ograniczyć dopasowanie symboli wieloznacznych według typu pliku. Na przykład dodanie (.)po wzorze ogranicza go do zwykłych plików.

wc -w *(.)

Aby poradzić sobie z nazwami plików rozpoczynającymi się od -lub ., użyj wc -c -- *(.N)lub wc -c ./*(.N). Jeśli chcesz dołączyć również dowiązania symboliczne do zwykłych plików, zrób to *(-.).

Inne popularne powłoki nie mają takiej funkcji, więc musisz użyć innego mechanizmu do filtrowania według plików, takiego jak testowanie typów plików w pętli lub find.

Gilles „SO- przestań być zły”
źródło
0

Bash dla pętli z wyłączeniem podkatalogów ('/') i linków (@):

for f in `ls|egrep -v '/|@'`; do echo $f; done
James Armstrong
źródło