W jaki sposób możesz sprawdzić, czy pliki o określonym rozszerzeniu znajdują się w katalogu za pomocą bash?
Coś jak
if [ -e *.flac ]; then
echo true;
fi
#!/bin/bash
count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo true
fi
ls -l
, moja odpowiedź używals -1
ls -1
wydrukuje jedną linię na plik\n
(i tak, jest to poprawne w nazwach plików).#/bin/bash myarray=(`find ./ -maxdepth 1 -name "*.py"`) if [ ${#myarray[@]} -gt 0 ]; then echo true else echo false fi
źródło
${#myarray[@]}
to 1ls -1 *.py
zamiast findUżywa ls (1), jeśli nie istnieją żadne pliki flac, ls zgłasza błąd i skrypt kończy pracę; w przeciwnym razie skrypt jest kontynuowany, a pliki mogą być przetwarzane
#! /bin/sh ls *.flac >/dev/null || exit ## Do something with flac files here
źródło
if ls *.flac >/dev/null 2>&1; then ... fi;
shopt -s nullglob if [[ -n $(echo *.flac) ]] # or [ -n "$(echo *.flac)" ] then echo true fi
źródło
Musisz uważać, którą flagę wrzucisz do swojego
if
oświadczenia i jaki ma to związek z oczekiwanym wynikiem.Jeśli chcesz sprawdzić tylko zwykłe pliki, a nie inne typy wpisów systemu plików, będziesz chciał zmienić szkielet kodu na:
if [ -f file ]; then echo true; fi
Użycie
-f
ograniczenia ogranicza sięif
do zwykłych plików, podczas gdy-e
jest bardziej ekspansywne i będzie pasować do wszystkich typów wpisów systemu plików. Istnieją oczywiście inne opcje, takie jak-d
katalogi itp. Zobacz http://tldp.org/LDP/abs/html/fto.html aby uzyskać dobrą listę.Jak wskazał @msw,
test
(tj.[
) Dusi się, jeśli spróbujesz podać więcej niż jeden argument. Może się to zdarzyć w twoim przypadku, jeśli glob for*.flac
zwrócił więcej niż jeden plik. W takim przypadku spróbuj zawinąćif
test w pętlę, taką jak:for file in ./*.pdf do if [ -f "${file}" ]; then echo 'true'; break fi done
W ten sposób
break
na pierwszym wystąpieniu żądanego rozszerzenia pliku możesz kontynuować pracę nad resztą skryptu.źródło
test
(aka[
) narzeka, jeśli wzorzec rozwija się do więcej niż jednego pliku: „oczekiwano operatora binarnego” lub „za dużo argumentów”"$file"
, ponieważ nazwa pliku może zawierać złe znaki, takie jak spacje lub gwiazdki.#!/bin/bash files=$(ls /home/somedir/*.flac 2> /dev/null | wc -l) if [ "$files" != "0" ] then echo "Some files exists." else echo "No files with that extension." fi
źródło
Najlepsze rozwiązanie
(if [ -e *.flac ];)
u mnie nie działało, dając:[: too many arguments
if ls *.flac >/dev/null 2>&1;
wtedy to zadziała.źródło
Możesz użyć -f, aby sprawdzić, czy istnieją pliki określonego typu:
#!/bin/bash if [ -f *.flac ] ; then echo true fi
źródło
[
(w przeciwieństwie do bardziej powszechnego[[
) nie zapobiega globbingowi.shopt -s nullglob set -- $(echo *.ext) if [ "${#}" -gt 0 ];then echo "got file" fi
źródło
-ge
zamiast tego-gt
, ponieważ w przeciwnym razie kod nie wykryje pojedynczego pliku. Po drugie, jeśli nie ma plików pasujących do wzorca, każda zgodna powłoka pozostawi ciąg*.ext
nietknięty, więc nadal otrzymasz jeden „wynik”.tylko bash:
any_with_ext () ( ext="$1" any=false shopt -s nullglob for f in *."$ext"; do any=true break done echo $any ) if $( any_with_ext flac ); then echo "have some flac" else echo "dir is flac-free" fi
Używam nawiasów zamiast nawiasów klamrowych, aby upewnić się, że używana jest podpowłoka (nie chcę przebijać bieżących
nullglob
ustawień).źródło
Oto rozwiązanie wykorzystujące bez zewnętrznych poleceń (tj. Nie
ls
), ale zamiast tego funkcję powłoki. Przetestowane w bash:shopt -s nullglob function have_any() { [ $# -gt 0 ] } if have_any ./*.flac; then echo true fi
Funkcja
have_any
używa$#
do liczenia argumentów, a[ $# -gt 0 ]
następnie sprawdza, czy istnieje co najmniej jeden argument. Użycie./*.flac
zamiast tylko*.flac
w wywołaniu funkcjihave_any
ma na celu uniknięcie problemów powodowanych przez pliki o nazwach takich jak--help
.źródło
Aby zakończyć, z zsh:
if [[ -n *.flac(#qN) ]]; then echo true fi
Jest to wymienione na końcu sekcji Wyrażenia warunkowe w podręczniku zsh. Ponieważ
[[
wyłącza tworzenie nazw plików, musimy wymusić generowanie nazwy pliku, używając(#q)
na końcu globalnego ciągu znaków, a następnieN
flagi (NULL_GLOB
opcji), aby wymusić, że wygenerowany ciąg będzie pusty w przypadku braku dopasowania.źródło
Oto dość proste rozwiązanie:
if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi
Jak widać, jest to tylko jedna linia kodu, ale działa wystarczająco dobrze. Powinien działać zarówno z bashem, jak i powłoką zgodną z POSIX, taką jak myślnik. Rozróżnia również wielkość liter i nie dba o to, jakie typy plików (zwykłe, dowiązanie symboliczne, katalog itp.) Są obecne, co może być przydatne, jeśli masz jakieś dowiązania symboliczne lub coś w tym rodzaju.
źródło
Próbowałem tego:
if [ -f *.html ]; then echo "html files exist" else echo "html files dont exist" fi
Użyłem tego fragmentu kodu bez problemu dla innych plików, ale dla plików html otrzymałem błąd :
Następnie wypróbowałem rozwiązanie zliczania @ JeremyWeir, które zadziałało dla mnie.
Pamiętaj, że będziesz musiał zresetować licznik, jeśli robisz to w pętli:
count=$((0))
źródło
To powinno działać w każdej skorupie podobnej do przenoszonej:
if [ "$(find . -maxdepth 1 -type f | grep -i '.*\.flac$')" ]; then echo true fi
Działa to również z GNU
find
, ale IDK, jeśli jest to zgodne z innymi implementacjamifind
:if [ "$(find . -maxdepth 1 -type f -iname \*.flac)" ]; then echo true fi
źródło