GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie verwende ich Platzhalter in einem xargs-Befehl?

Du warst ganz nah dran.

seq 15 -1 1 | xargs [email protected] sh -c 'mv @_* @'

Sie müssen die Interpretation (Erweiterung) des * verzögern bis nach @ eine Substitution stattgefunden hat. (Aber Sie haben bereits verstanden, dass das das Problem war, oder?)

Mir wurde geraten, niemals einen unbekannten Dateinamen (oder eine andere Ersatzzeichenfolge) direkt in eine Shell-Befehlszeile einzubetten. Das obige Beispiel ist wahrscheinlich ziemlich sicher, da Sie wissen, wie die Zeichenfolgen lauten werden – 15 , 14 , …, 3 , 2 und 1 . Aber das obige Beispiel als Vorlage für komplexere Befehle zu verwenden, kann gefährlich sein. Eine sicherere Anordnung wäre

seq 15 -1 1 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @

wobei x-sh ist eine halb willkürliche Zeichenfolge, die verwendet wird, um alle Fehlermeldungen zu kennzeichnen, die von der aufgerufenen Shell ausgegeben werden. Dies entspricht meinem ersten Beispiel, außer dass die Zeichenfolgen nicht eingebettet werden (dargestellt durch @ ) direkt in den Shell-Befehl, fügt er sie ein, indem er den @ bereitstellt als Argument für die Shell und referenziert sie dann als "$1" .

P.S. Sie haben vorgeschlagen, seq auszuführen Befehl umgekehrt (seq 15 -1 1 , was 15 generiert , 14 , …, 3 , 2 , 1 statt 1 , 2 , 3 , …, 14 , 15 ) und niemand hat es erwähnt. Dies wäre ein wichtiger Teil der Antwort, wenn Ihre Dateinamen wie 1foo.txt wären , 2bar.asc , und 13test.png , usw. (mit verschiedenen Zeichen, die nach der Nummer erscheinen, anstatt immer _ ). In diesem Fall wäre der Befehl mv "$1"* "$1" (ohne den _ ), und wenn Sie 1 getan haben zuerst, dann den Befehl mv 1* 1 würde alle 10quick* wegfegen , 11brown* , 12fox* , etc., Dateien, zusammen mit dem 1foo* Dateien. Aber

seq 1 15 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @

sollte sicher sein.

P.S.S. Der seq Befehl wird nicht von POSIX angegeben. Auch keine Verstrebungserweiterung in der Schale. Eine POSIX-konforme Lösung kann konstruiert werden, indem die Antwort von grawity auf diese Frage mit dieser anderen Antwort von Adam Katz kombiniert wird:

i=1
while [ "$i" -le 15 ]
do
    mv -- "${i}"_* "$i"
    i=$((i+1))
done

P.P.P.S. Es ist nicht kritisch, wenn Sie wissen, dass die Dateinamen mit alphanumerischen Zeichen (d. h. Buchstaben und Ziffern) beginnen, aber in allgemeineren Fällen sollten Sie -- verwenden zwischen dem Befehlsnamen und den Argumenten. Dies verbessert die Handhabung von Dateinamen, die mit einem Bindestrich beginnen. Der -- weist den Befehl an, das Argument (den Dateinamen)als zu behandeln ein Argument. Ohne sie könnte ein solches Argument als Optionszeichenfolge behandelt werden.


Verwenden Sie einfach nicht xargs dafür. Verwenden Sie einen for Schleife:

for i in $(seq 1 15); do
    mv ${i}_* $i
done

Noch besser ist es, Klammererweiterung statt seq zu verwenden :

mkdir {1..15}

for i in {1..15}; do
    mv ${i}_* $i
done

Linux
  1. So verwenden Sie BusyBox unter Linux

  2. So verwenden Sie Bash-Verlaufsbefehle

  3. Wie ich Cron unter Linux verwende

  4. So verwenden Sie FIND unter Linux

  5. So verwenden Sie Nginx zum Umleiten

So verwenden Sie den Linux-nohup-Befehl

So verwenden Sie Traceroute unter Kali Linux

So verwenden Sie Instagram im Terminal

So verwenden Sie den PS-Befehl

So verwenden Sie den TOP-Befehl

So verwenden Sie FTP