Was macht diese Befehlszeile (`echo $1 | xargs -n 1 basename | cut -d '.' -f1`)?

Was macht diese Befehlszeile (`echo $1 | xargs -n 1 basename | cut -d '.' -f1`)?

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.worldund analysiert das helloBit.

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 $1ist das erste Argument in der Befehlszeile (für das Skript oder die Shell-Funktion, zu der es gehört).

xargs -n 1 basenameDer einzige Grund für die Verwendung von „plain“ liegt wahrscheinlich basenamedarin, dass das basenameDienstprogramm nicht von der Standardeingabe liest, sondern „ xargsplain“ verwendet.

Eine kürzere (und schnellere) Version derselben Sache in bashoder ksh93wä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 echound xargsist hier ziemlich merkwürdig.

basenamenimmt einen Pfadnamen in der Befehlszeile und gibt die letzte Komponente davon aus (normalerweise also den Teil nach dem letzten Schrägstrich). xargsplatziert einfach die Wörter, die von seiner Eingabe (der Pipe) gelesen werden, in die Befehlszeile von basenamehier. Warum also nicht einfach verwenden basename $1?

Es gibt jedoch einen Unterschied.

Wenn echo $1 | xargs -n 1 basenameder Parameter $1Leerzeichen enthält, xargswird er in Leerzeichen aufgeteilt und basenamejedes 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 cutasKusalananda 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 $1druckt 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 '.' -f1entfernt die Erweiterung.

Wenn Sie beispielsweise

echo directory/test.sh | xargs -n 1 basename | cut -d '.' -f1

das Ergebnis (gespeichert unter $file) wird sein test.

verwandte Informationen