for i in $(ls);do
if [ $i = '*.java' ];then
echo "I do something with the file $i"
fi
done
Chcę przejrzeć każdy plik w bieżącym folderze i sprawdzić, czy pasuje do określonego rozszerzenia. Powyższy kod nie działa, czy wiesz dlaczego?
for i in $(ls *.java); do echo "do something with file $i"; done
?$i
z literałem „* .java”; ekspansja wzorca nie jest tutaj wykonywana.if [[ $i == *.java ]]; then
.. (zwróć uwagę na podwójne [[]] si niecytowane * .java).ls
- zaakceptuj odpowiedź @ chepnerOdpowiedzi:
Żadne wymyślne sztuczki nie są potrzebne:
Strażnik zapewnia, że jeśli nie ma pasujących plików, pętla zakończy działanie bez próby przetworzenia nieistniejącej nazwy pliku
*.java
. Wbash
(lub powłokach obsługujących coś podobnego) możesz użyćnullglob
opcji, aby po prostu zignorować nieudane dopasowanie i nie wchodzić w treść pętli.źródło
for i in *.java *.cpp; do
. Jeśli rozszerzony wzory odblokowanebash
zshopt -s extglob
, można napisaćfor i in *.@(java|cpp); do
.shopt -s nullglob
aby niepasujący wzorzec rozszerzał się do pustej sekwencji, a nie był traktowany dosłownie.cd
przejść do tego katalogu przed rozpoczęciemfor
pętlinullglob
traktowanie go jako pustej sekwencji lub ustawićfailglob
jako błąd. (Jeśli ustawisz oba,failglob
pierwszeństwo ma.)prawidłowa odpowiedź to @ chepner's
jednak oto mała sztuczka, aby sprawdzić, czy nazwa pliku ma dane rozszerzenia:
źródło
ext
zamiast.java
?Rekurencyjnie dodawaj podfoldery,
źródło
find . -name "*.java" -type f -exec echo \{\} \;
uniknąć błędnej interpretacji wynikówfind
"$i"
wewnątrz pętli.Pętli wszystkich plików kończących się:
.img
,.bin
,.txt
przyrostek i wydrukować nazwę pliku:Lub rekurencyjnie (znajdź także we wszystkich podkatalogach):
źródło
Zgadzam się z innymi odpowiedziami dotyczącymi prawidłowego sposobu przeglądania plików. Jednak PO zapytał:
Tak!
Doskonały artykuł Jaka jest różnica między testem [i [?] Wyjaśnia szczegółowo, że pośród innych różnic nie można używać polecenia
expression matching
lubpattern matching
w ramachtest
polecenia (co jest skrótem[
)To jest powód niepowodzenia twojego skryptu. Jeśli OP jest zainteresowany odpowiedzią ze
[[
składnią (która ma tę wadę, że nie jest obsługiwana na tylu platformach, co[
polecenie), byłbym szczęśliwy, aby edytować moją odpowiedź, aby ją uwzględnić.EDYCJA: przydatne byłyby wszelkie wskazówki dotyczące formatowania danych w odpowiedzi jako tabeli!
źródło
jak mówi @chepner w swoim komentarzu, porównujesz $ i do ustalonego ciągu.
Aby rozwinąć i naprawić sytuację, powinieneś użyć [[]] z operatorem regex = ~
na przykład:
wyrażenie regularne po prawej stronie = ~ jest sprawdzane pod kątem wartości operatora po lewej stronie i nie powinno być cytowane (cudzysłów nie spowoduje błędu, ale zostanie porównany z ustalonym ciągiem, więc najprawdopodobniej zakończy się niepowodzeniem "
ale odpowiedź @chepnera powyżej przy użyciu globu jest znacznie wydajniejszym mechanizmem.
źródło
ext
zamiast.java
?if [[ $i == *.java ]]
lubif [[ $i == *.$ext ]]
. Ale nie analizuj lsUważam, że to rozwiązanie jest bardzo przydatne. Wykorzystuje
-or
opcję wfind
:find . -name \*.tex -or -name "*.png" -or -name "*.pdf"
Będzie znaleźć pliki z rozszerzeniem
tex
,png
ipdf
.źródło