Ich muss diese Befehlszeile verstehen:
file=`echo $1 | xargs -n 1 basename | cut -d '.' -f1`
Antwort1
Es weist der Variable einen Teil eines Dateinamens (möglicherweise mit Pfad) zu file
. Genauer gesagt, das Bit vor dem ersten .
Zeichen im Dateinamen der Datei selbst. Mit anderen Worten, es nimmt etwas wie /some/path/hello.world
und analysiert das hello
Bit.
Ein Tipp wäre, jeden Teil der Pipeline auf der Befehlszeile auszuführen:
$ thing="/some/path/hello.world"
$ echo "$thing"
/some/path/hello.world
$ echo "$thing" | xargs -n 1 basename
hello.world
$ echo "$thing" | xargs -n 1 basename | cut -d '.' -f 1
hello
Die Backticks werden verwendet, um die Ausgabe der Pipeline zurückzugeben und sie zuzuweisen file
. Dies $1
ist das erste Argument in der Befehlszeile (für das Skript oder die Shell-Funktion, zu der es gehört).
xargs -n 1 basename
Der einzige Grund für die Verwendung von „plain“ liegt wahrscheinlich basename
darin, dass das basename
Dienstprogramm nicht von der Standardeingabe liest, sondern „ xargs
plain“ verwendet.
Eine kürzere (und schnellere) Version derselben Sache in bash
oder ksh93
wäre
file=${1##*/}
file=${file%%.*}
Antwort2
Die Zeile extrahiert die Dateinamen ohne Erweiterungen aus Pfaden, die über $1
(das erste Argument des Skripts, in dem diese Zeile erscheint) bereitgestellt werden. Das Ergebnis wird in der Variable gespeichert file
.
Demo:
$ echo /etc/dhcpcd.conf ../foo/bar/filename.tar.gz | xargs -n 1 basename | cut -d '.' -f1
dhcpcd
filename
Antwort3
Die Kombination von echo
und xargs
ist hier ziemlich merkwürdig.
basename
nimmt einen Pfadnamen in der Befehlszeile und gibt die letzte Komponente davon aus (normalerweise also den Teil nach dem letzten Schrägstrich). xargs
platziert einfach die Wörter, die von seiner Eingabe (der Pipe) gelesen werden, in die Befehlszeile von basename
hier. Warum also nicht einfach verwenden basename $1
?
Es gibt jedoch einen Unterschied.
Wenn echo $1 | xargs -n 1 basename
der Parameter $1
Leerzeichen enthält, xargs
wird er in Leerzeichen aufgeteilt und basename
jedes Wort einzeln aufgerufen. Das Endergebnis ist, dass ein Teil des Dateinamens ausgewählt wird füralledie Worte, wieArminius zeigte.
Die andere Option, basename $1
, würde nur einmal aufrufen basename
(und aufgrund der Worttrennung auf nette Weise fehlschlagen.)
Wenn der Befehl nur einen Dateinamen verarbeiten soll, wäre es besser, ihn wie folgt zu schreiben:
file=$(basename "$1" | cut -d '.' -f 1)
Mit den Anführungszeichen. (oder mit der Shell-Erweiterung zum Entfernen von Suffixen ${file%%.*}
anstelle von cut
asKusalananda zeigte.)
Wenn andererseits mehrere Dateinamen verarbeitet werden sollen, ist es möglicherweise sauberer, sie mithilfe eines Arrays oder in den Positionsparametern (alle, nicht nur $1
) zu übergeben.
Antwort4
Die Zeile speichert den Namen einer Datei ohne Erweiterung und Pfad in der Variablen $file
.
Im Detail:
echo $1
druckt das erste an das Skript übergebene Befehlszeilenargument, xargs -n 1 basename
übergibt die zurückgegebene Zeichenfolge als Argumente an den Befehl basename
, der den Pfad aus dem Dateinamen entfernt.
cut -d '.' -f1
entfernt die Erweiterung.
Wenn Sie beispielsweise
echo directory/test.sh | xargs -n 1 basename | cut -d '.' -f1
das Ergebnis (gespeichert unter $file
) wird sein test
.