Вы были очень близки
seq 15 -1 1 | xargs -I@ sh -c 'mv @_* @'
Вам нужно отложить интерпретацию (расширение) *
до тех пор, пока не произойдет замена @
.
(Но вы уже поняли, что это была проблема, верно?)
Мне посоветовали никогда не вставлять неизвестное имя файла (или другую строку подстановки) непосредственно в командную строку оболочки.
Приведенный выше пример, вероятно, довольно безопасен, потому что вы знаете, какими будут строки - 15
, 14
,…, 3
, 2
и 1
.
Но использование приведенного выше примера в качестве шаблона для более сложных команд может быть опасным.
Более безопасное соглашение будет
seq 15 -1 1 | xargs -I@ sh -c 'mv "$1"_* "$1"' x-sh @
где x-sh
- произвольная строка, которая будет использоваться для обозначения любых сообщений об ошибках, генерируемых вызванной оболочкой.
Это эквивалентно моему первому примеру, за исключением того, что вместо встраивания строк (представленных @
) непосредственно в команду оболочки, он внедряет их, предоставляя @
в качестве аргумента для оболочки, а затем ссылается на них как "$1"
.
PS Вы предложили запустить команду seq
в обратном порядке (seq 15 -1 1
, которая генерирует 15
, 14
,…, 3
, 2
, 1
а не 1
, 2
, 3
,…, 14
, 15
), и никто не упомянул об этом.
Это было бы важной частью ответа, если бы ваши имена файлов были такими, как 1foo.txt
, 2bar.asc
, 13test.png
и т.д. (С различными символами, появляющимися после числа, а не всегда _
).
В этом случае команда будет mv "$1"* "$1"
(без _
), и, если вы сначала сделали 1
, то команда mv 1* 1
сместит все 10quick*
, 11brown*
, 12fox*
и т. д., файлы вместе с 1foo*
.
Но
seq 1 15 | xargs -I@ sh -c 'mv "$1"_* "$1"' x-sh @
должен быть в безопасности.
PPS Команда seq
не указана в POSIX. Также нет расширения скобки в оболочке.
POSIX-совместимое решение может быть построено, комбинируя ответ Гравити на этот вопрос с другим ответом Адама Каца:
i=1
while [ "$i" -le 15 ]
do
mv "${i}"_* "$i"
i=$((i+1))
done