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