Du warst ganz nah dran.
seq 15 -1 1 | xargs example@unixlinux.online 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 example@unixlinux.online 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 example@unixlinux.online 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