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.

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

@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.


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.


0

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

for f in `ls|egrep -v '/|@'`; do echo $f; done
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.