Próbuję znaleźć wszystkie pliki z określonym rozszerzeniem w katalogu i jego podkatalogach za pomocą bash (najnowsza wersja Ubuntu LTS).
Oto, co jest zapisane w pliku skryptu:
#!/bin/bash
directory="/home/flip/Desktop"
suffix="in"
browsefolders ()
for i in "$1"/*;
do
echo "dir :$directory"
echo "filename: $i"
# echo ${i#*.}
extension=`echo "$i" | cut -d'.' -f2`
echo "Erweiterung $extension"
if [ -f "$i" ]; then
if [ $extension == $suffix ]; then
echo "$i ends with $in"
else
echo "$i does NOT end with $in"
fi
elif [ -d "$i" ]; then
browsefolders "$i"
fi
done
}
browsefolders "$directory"
Niestety, kiedy uruchamiam ten skrypt w terminalu, mówi:
[: 29: in: unexpected operator
(z $extension
zamiast 'in'
)
Co tu się dzieje, gdzie jest błąd? Ale ten nawias klamrowy
Odpowiedzi:
jest nieco krótszy niż to wszystko (i bezpieczniejszy - zajmuje się białymi znakami w nazwach plików i nazwach katalogów).
Twój skrypt prawdopodobnie nie działa w przypadku wpisów, które nie mają
.
w nazwie, dlatego są$extension
puste.źródło
find
domyślnie jest rekurencyjny. możesz ograniczyć głębokości, jeśli chcesz (patrz strona podręcznika).Przykład: Aby znaleźć wszystkie
csv
pliki w bieżącym katalogu i jego podkatalogach, użyj:źródło
Używana przeze mnie składnia jest nieco inna niż sugerowana przez @Matt:
(to jeden klawisz mniej).
źródło
Bez użycia
find
:źródło
grep
nie jest tak naprawdę konieczne.awk
ma wyrażenia regularne i może ograniczyć wynik do wartości pasujących do wzorca.awk|grep
jest anty-wzorem. Niech awk zrobi grepping.{
brakuje pobrowsefolders ()
$in
powinno być$suffix
cut
pokazuje tylko środkową częśćfront.middle.extension
. Powinieneś przeczytać instrukcję obsługi${varname%%pattern}
i znajomych.Zakładam, że robisz to jako ćwiczenie skryptów powłoki, w przeciwnym razie
find
rozwiązanie już zaproponowane jest dobrym rozwiązaniem.Aby sprawdzić poprawną składnię powłoki, bez uruchamiania skryptu, użyj
sh -n scriptname
.źródło
źródło
Chociaż użycie
find
polecenia może być przydatne tutaj, sama powłoka zapewnia opcje umożliwiające spełnienie tego wymagania bez narzędzi innych firm.bash
Powłoka zapewnia rozszerzoną opcję pomocy glob za pomocą którego można uzyskać nazwy plików pod rekurencyjnych ścieżek że mecz z rozszerzeniami, które chcesz.Rozszerzona opcja jest tym,
extglob
co należy ustawić za pomocąshopt
opcji przedstawionej poniżej. Opcje są włączone z-s
obsługą i wyłączone z-u
flagą on . Dodatkowo możesz użyć kilku opcji więcej, tj.nullglob
W którym niezrównany glob zostaje całkowicie zmieciony, zastąpiony zestawem zerowych słów. Iglobstar
który pozwala na przeszukanie przez wszystkich katalogówTeraz wystarczy utworzyć wyrażenie glob, aby uwzględnić pliki określonego rozszerzenia, które można wykonać w sposób opisany poniżej. Używamy tablicy do wypełniania wyników globalnych, ponieważ przy prawidłowym cytowaniu i rozwinięciu nazwy plików ze znakami specjalnymi pozostałyby nienaruszone i nie uległyby uszkodzeniu z powodu podziału słów przez powłokę.
Na przykład, aby wyświetlić listę wszystkich
*.csv
plików w ścieżkach rekurencyjnychOpcja
**
polega na ponownym przechodzeniu przez podfoldery i*.csv
jest rozszerzeniem globalnym w celu włączenia dowolnego pliku wymienionych rozszerzeń. Teraz do drukowania rzeczywistych plików, po prostu zróbUżywanie tablicy i poprawne cytowanie rozszerzenia jest właściwym sposobem, gdy jest używane w skryptach powłoki, ale do użytku interaktywnego można po prostu użyć
ls
wyrażenia glob jakoMożna to bardzo dobrze rozszerzyć, aby pasowało do wielu plików, tj. Plik kończący się wieloma rozszerzeniami (tj. Podobnie jak dodawanie wielu flag w
find
poleceniu). Dla przykładu rozważmy przypadek konieczności, aby wszystkie pliki graficzne rekurencyjnych czyli rozszerzeń*.gif
,*.png
a*.jpg
wszystko, czego potrzebujesz do IsMożna to bardzo dobrze rozszerzyć, aby również miało negatywne wyniki. Przy tej samej składni można użyć wyników globu, aby wykluczyć pliki określonego typu. Załóżmy, że chcesz wykluczyć nazwy plików z powyższymi rozszerzeniami, możesz to zrobić
Konstrukt
!()
jest operacją negowania, która nie obejmuje żadnego z rozszerzeń plików wymienionych w środku, i|
jest operatorem naprzemiennym, tak jak jest używany w bibliotece Rozszerzonych wyrażeń regularnych, aby wykonać dopasowanie LUB globów.Zauważ, że ta rozszerzona obsługa globów nie jest dostępna w powłoce bourne POSIX i jest ona specyficzna dla ostatnich wersji
bash
. Więc jeśli zastanawiasz się nad przenośnością skryptów działających w POSIX ibash
powłokach, ta opcja nie byłaby właściwa.źródło
Aby znaleźć wszystkie
pom.xml
pliki w bieżącym katalogu i wydrukować je, możesz użyć:źródło
źródło
źródło