
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml | head -1 | xargs basename`
Ich wollte den zweiten Befehl ( head -1
) nur ausführen, wenn der erste Befehl erfolgreich ist. Wie kann ich diesen Befehl verbessern?
Antwort1
Versuche dies:
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml | head -1 | xargs -r basename`
Das Übergeben xargs
des -r
Flags führt dazu, dass es nur ausgeführt wird, basename
wenn mindestens ein Element von der Standardeingabe ( head -1
) gelesen wird.
head -1
wird ausgeführt, aber Sie sehen oder erfassen keine Ausgabe davon.
Wenn Sie nicht möchten, dass der Benutzer Fehlerausgaben von sieht ls
, können Sie ls
den Stderr-Stream von zu umleiten /dev/null
.
INPUT_FILE=`ls -rt "$MY_DIR"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename`
Beachten Sie auch, dass ich Anführungszeichen hinzugefügt habe $MY_DIR
. Auf diese Weise schlägt der Befehl nicht fehl, wenn $MY_DIR
er Leerzeichen enthält.
Wenn Sie eine moderne Shell wie Bash verwenden, sollten Sie $( )
anstelle von Backticks eine Capture-Shell verwenden. Sie sollten auch erwägen, den Stil Ihrer Variablen zu ändern. Sie sollten generell vermeiden, in Skripten ausschließlich Variablennamen in Großbuchstaben zu verwenden. Dieser Stil ist im Allgemeinen reservierten und Umgebungsvariablen vorbehalten.
input_file=$(ls -rt "$my_dir"/FILE.*.xml 2> /dev/null | head -1 | xargs -r basename)
Antwort2
In einer Pipeline werden alle Befehle gleichzeitig gestartet und ausgeführt, nicht einer nach dem anderen. Sie müssen die Ausgabe also irgendwo speichern.
if ls_output=$(ls -rtd -- "$MY_DIR"/FILE.*.xml); then
first_file=$(printf '%s\n' "$ls_output" | head -n 1)
first_file_name=$(basename -- "$first_file")
fi
Beachten Sie, dass davon ausgegangen wird, dass Dateinamen keine Zeilenumbruchzeichen enthalten. Die Verwendung von xargs
würde auch Probleme mit Leerzeichen, einfachen und doppelten Anführungszeichen und Backslashes bedeuten. Das Weglassen von Variablen ohne Anführungszeichen würde Probleme mit Leerzeichen, Tabulatoren und Platzhalterzeichen bedeuten. Das Vergessen --
würde Probleme mit Dateinamen bedeuten, die mit beginnen -
.
So erhalten Sie den Basisnamen der ältesten Datei zsh
ohne diese Zeichenbeschränkungen (umgeht außerdem das Problem der begrenzten Größe der Argumente eines Befehls):
first_file_name=($MY_DIR/FILE.*.xml(Om[1]:t))
Wenn keine Übereinstimmung gefunden wird, schlägt der Befehl fehl und das Skript wird abgebrochen. Sie können auch Folgendes tun:
first_file_name=($MY_DIR/FILE.*.xml(NOm[1]:t))
In diesem Fall first_file_name
enthält das Array 1 Element, wenn eine Übereinstimmung vorliegt, und 0, wenn nicht. Sie können dann Folgendes tun:
if (($#first_file_name)); then
printf 'Match: %s\n' $first_file_name
else
echo >&2 No match
fi
Antwort3
Suchen Sie die zuletzt geänderte Datei in einem Verzeichnis:
latest() {
local file path=${1:-.} ext=${2-} latest
for file in "${path%/}"/*"$ext"; do
[[ $file -nt $latest ]] && latest=$file
done
[[ $latest ]] && printf '%s\n' "$latest"
}
Verwendung:latest [directory/path/ [.extension]]
Verwenden Sie anstelle des Aufrufs basename
die Parametererweiterung.
in_file=$(latest in/my/dir .xml)
base_fn=${in_file##*/} base_fn=${base_fn%.*}
In einem Verzeichnis mit diesem Inhalt:
foo.xml bar.xml baz.xml newest.xml
Der Inhalt der Variable base_fn wäre:newest
So verwenden Sie es ordnungsgemäß, um den Zweck Ihrer Anfrage zu erfüllen:
check_dir=/path/to/check
check_ext=.xml
if in_file=$(latest "$check_dir" "$check_ext"); then
base_fn=${in_file##*/} base_fn=${base_fn%.*}
else
printf '%s\n' "No file found in $check_dir" >&2
fi
EDIT: bei der Überprüfung der Frage habe ich festgestellt, dass der ls
fragliche Befehl nach dem suchtältesteDatei in einem Verzeichnis. Diese gleiche Funktion könnte umbenannt werden in oldest
und hätte [[ $file -ot $oldest ]] && oldest=$file
stattdessen, um denselben Effekt zu erzielen. Entschuldigen Sie etwaige Verwirrung.
Wichtig zu beachten ist, dass Sie die Ausgabe von ls auf keinen Fall und unter keinen Umständen analysieren sollten. Niemals.
Antwort4
Ich denke, die beste Option ist hier:
ls -rf $MY_DIR/FILE.*.xml
if [ $? -eq 0 ]; then
INPUT_FILE=`ls -rt $MY_DIR/FILE.*.xml|head -1|xargs basename `
else
echo "Error!"
fi
Wenn keine Datei vorhanden ist, lautet der Rückgabecode von ls 2. Wenn jedoch eine Datei gefunden wird, lautet der Rückgabecode 0.