Wie würden Sie mit bash feststellen, ob Dateien einer bestimmten Erweiterung in einem Verzeichnis vorhanden sind?
Etwas wie
if [ -e *.flac ]; then
echo true;
fi
Antworten:
#!/bin/bash
count=`ls -1 *.flac 2>/dev/null | wc -l`
if [ $count != 0 ]
then
echo true
fi
ls -l
, meine Antwort benutztls -1
ls -1
eine Zeile pro Datei
\n
(und ja, das ist in Dateinamen gültig).
#/bin/bash
myarray=(`find ./ -maxdepth 1 -name "*.py"`)
if [ ${#myarray[@]} -gt 0 ]; then
echo true
else
echo false
fi
${#myarray[@]}
1
ls -1 *.py
anstelle von find
Dies verwendet ls (1). Wenn keine flac-Dateien vorhanden sind, meldet ls einen Fehler und das Skript wird beendet. Andernfalls wird das Skript fortgesetzt und die Dateien können verarbeitet werden
#! /bin/sh
ls *.flac >/dev/null || exit
## Do something with flac files here
if ls *.flac >/dev/null 2>&1; then ... fi;
shopt -s nullglob
if [[ -n $(echo *.flac) ]] # or [ -n "$(echo *.flac)" ]
then
echo true
fi
Sie müssen vorsichtig sein, welche Flagge Sie in Ihre if
Aussage werfen und wie sie sich auf das gewünschte Ergebnis bezieht.
Wenn Sie nur nach regulären Dateien und nicht nach anderen Arten von Dateisystemeinträgen suchen möchten, sollten Sie Ihr Codeskelett ändern in:
if [ -f file ]; then
echo true;
fi
Die Verwendung von -f
beschränkt sich if
auf reguläre Dateien, -e
ist jedoch umfangreicher und entspricht allen Arten von Dateisystemeinträgen. Es gibt natürlich auch andere Optionen wie -d
für Verzeichnisse usw. Eine gute Auflistung finden Sie unter http://tldp.org/LDP/abs/html/fto.html .
Wie von @msw hervorgehoben, wird test
(dh [
) ersticken, wenn Sie versuchen, mehr als ein Argument einzugeben . Dies kann in Ihrem Fall passieren, wenn der Glob für *.flac
mehr als eine Datei zurückgegeben hat. Versuchen Sie if
in diesem Fall, Ihren Test in eine Schleife wie folgt zu verpacken :
for file in ./*.pdf
do
if [ -f "${file}" ]; then
echo 'true';
break
fi
done
Auf diese Weise können Sie break
bei der ersten Instanz der gewünschten Dateierweiterung mit dem Rest des Skripts fortfahren.
test
(aka [
) beschwert sich, wenn das Muster auf mehr als eine Datei erweitert wird: "Binäroperator erwartet" oder "zu viele Argumente"
"$file"
, da der Dateiname einige fehlerhafte Zeichen wie Leerzeichen oder Sternchen enthalten kann.
Die Top-Lösung (if [ -e *.flac ];)
hat bei mir nicht funktioniert.[: too many arguments
if ls *.flac >/dev/null 2>&1;
dann wird es funktionieren.
shopt -s nullglob
set -- $(echo *.ext)
if [ "${#}" -gt 0 ];then
echo "got file"
fi
-ge
stattdessen -gt
, weil Ihr Code sonst die einzelne Datei nicht erkennt. Zweitens, wenn keine Dateien vorhanden sind, die dem Muster entsprechen, bleibt die Zeichenfolge durch eine konforme Shell *.ext
unberührt, sodass Sie immer noch ein "Ergebnis" erhalten.
Mit -f können Sie überprüfen, ob Dateien eines bestimmten Typs vorhanden sind:
#!/bin/bash
if [ -f *.flac ] ; then
echo true
fi
[
(im Gegensatz zu der üblicheren [[
) das Globbing nicht verhindert.
Nur 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
Ich verwende Klammern anstelle von geschweiften Klammern, um sicherzustellen, dass eine Unterschale verwendet wird (ich möchte Ihre aktuelle nullglob
Einstellung nicht beeinträchtigen ).
Hier ist eine Lösung, die keine externen Befehle (dh nein ls
) verwendet, sondern stattdessen eine Shell-Funktion. In Bash getestet:
shopt -s nullglob
function have_any() {
[ $# -gt 0 ]
}
if have_any ./*.flac; then
echo true
fi
Die Funktions have_any
Verwendungen $#
ihre Argumente zu zählen, und [ $# -gt 0 ]
dann prüfen , ob es zumindest ein Argument ist. Die Verwendung von ./*.flac
statt nur *.flac
im Aufruf von have_any
dient dazu, Probleme zu vermeiden, die durch Dateien mit Namen wie verursacht werden --help
.
Zur Vervollständigung mit zsh:
if [[ -n *.flac(#qN) ]]; then
echo true
fi
Dies ist am Ende des Abschnitts Bedingte Ausdrücke im zsh-Handbuch aufgeführt. Da das [[
Globbing von Dateinamen deaktiviert ist, müssen wir die Generierung von Dateinamen (#q)
am Ende der Globbing-Zeichenfolge erzwingen und dann das N
Flag ( NULL_GLOB
Option), um zu erzwingen, dass die generierte Zeichenfolge leer ist, falls keine Übereinstimmung vorliegt.
Hier ist eine ziemlich einfache Lösung:
if [ "$(ls -A | grep -i \\.flac\$)" ]; then echo true; fi
Wie Sie sehen können, ist dies nur eine Codezeile, aber es funktioniert gut genug. Es sollte sowohl mit Bash als auch mit einem Posix-kompatiblen Shell-ähnlichen Dash funktionieren. Es unterscheidet auch nicht zwischen Groß- und Kleinschreibung und es ist egal, welche Art von Dateien (regulär, Symlink, Verzeichnis usw.) vorhanden sind. Dies kann hilfreich sein, wenn Sie Symlinks oder ähnliches haben.
Ich habe es versucht:
if [ -f *.html ]; then
echo "html files exist"
else
echo "html files dont exist"
fi
Ich habe diesen Code problemlos für andere Dateien verwendet, aber für HTML-Dateien habe ich eine Fehlermeldung erhalten :
[: too many arguments
Ich habe dann die Zähllösung von @ JeremyWeir ausprobiert, die für mich funktioniert hat.
Denken Sie daran, dass Sie die Zählung zurücksetzen müssen, wenn Sie dies in einer Schleife tun:
count=$((0))