Byli jste si velmi blízcí.
seq 15 -1 1 | xargs [email protected] sh -c 'mv @_* @'
Musíte zpozdit interpretaci (rozšíření) *
až po @
došlo k substituci. (Ale už jste pochopili, že to byl problém, že?)
Bylo mi doporučeno nikdy nevkládat neznámý název souboru (nebo jiný substituční řetězec) přímo do příkazového řádku shellu. Výše uvedený příklad je pravděpodobně docela bezpečný, protože víte, jaké řetězce budou —15
, 14
, …, 3
, 2
a 1
. Ale použití výše uvedeného příkladu jako šablony pro složitější příkazy může být nebezpečné. Bezpečnější uspořádání by bylo
seq 15 -1 1 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @
kde x-sh
je semi-libovolný řetězec, který bude použit k označení všech chybových zpráv vydaných vyvolaným shellem. Toto je ekvivalentní mému prvnímu příkladu, kromě vkládání řetězců (reprezentovaných @
)přímo do příkazu shellu, vloží je zadáním @
jako argument pro shell a poté na ně odkazovat jako "$1"
.
P.S. Navrhli jste spustit seq
příkaz obráceně (seq 15 -1 1
, který vygeneruje 15
, 14
, …, 3
, 2
, 1
spíše než 1
, 2
, 3
, …, 14
, 15
) a nikdo se o tom nezmínil. Toto by byla důležitá část odpovědi, pokud by vaše názvy souborů byly jako 1foo.txt
, 2bar.asc
a 13test.png
, atd. (s různými znaky, které se objevují za číslem, nikoli vždy _
). V takovém případě by příkaz byl mv "$1"* "$1"
(bez _
), a pokud jste udělali 1
nejprve příkaz mv 1* 1
by smetlo všechny 10quick*
, 11brown*
, 12fox*
, atd., soubory spolu s 1foo*
soubory. Ale
seq 1 15 | xargs [email protected] sh -c 'mv -- "$1"_* "$1"' x-sh @
by mělo být bezpečné.
P.P.S. seq
příkaz není specifikován POSIX. Ani expanze výztuhy ve skořepině. Řešení vyhovující standardu POSIX lze vytvořit kombinací Grawityho odpovědi na tuto otázku s touto další odpovědí Adama Katze:
i=1
while [ "$i" -le 15 ]
do
mv -- "${i}"_* "$i"
i=$((i+1))
done
P.P.P.S. Není důležité, když víte, že názvy souborů začínají alfanumerickými znaky (tj. písmeny a číslicemi), ale v obecnějších případech byste měli použít --
mezi názvem příkazu a argumenty. To zlepšuje práci s názvy souborů, které začínají pomlčkou. --
říká příkazu, aby s argumentem (názvem souboru) zacházeljako argument. Bez něj by takový argument mohl být považován za řetězec voleb.
Jen nepoužívejte xargs
pro to. Použijte for
smyčka:
for i in $(seq 1 15); do
mv ${i}_* $i
done
Ještě lepší je použít rozšíření složené závorky místo seq
:
mkdir {1..15}
for i in {1..15}; do
mv ${i}_* $i
done