Команда Bash для удаления ведущих нулей из всех имен файлов

У меня есть каталог с кучей файлов с такими именами, как:

001234.jpg
001235.jpg
004729342.jpg

Я хочу удалить ведущие нули из всех имен файлов, поэтому у меня останется:

1234.jpg
1235.jpg
4729342.jpg

Я пробовал разные конфигурации sed, но не могу найти правильный синтаксис. Есть ли простой способ перечислить все файлы в каталоге, передать их через sed и либо переместить, либо скопировать их в новое имя файла без начальных нулей?


person George    schedule 15.01.2010    source источник
comment
Примечание: это усложнит сортировку.   -  person Evan Carroll    schedule 16.01.2010
comment
С помощью GNU coreutils ls -v будет сортировать числа естественным образом (используя расширения Glibc versionsort(3)/strverscmp(3)). Но да, в целом изменение числовых частей имен файлов, чтобы они больше не выстраивались по длине, меняет нормальный порядок сортировки.   -  person ephemient    schedule 16.01.2010


Ответы (8)


sed сам по себе не подходит для этого: вам также нужно использовать некоторые сценарии оболочки.

Посетите страницу Переименовать несколько файлов с помощью Linux, чтобы найти некоторые идеи. Одна из предложенных идей — использовать perl-скрипт rename:

rename 's/^0*//' *.jpg
person Simon Nickerson    schedule 15.01.2010
comment
Мне нравится эта команда, но, к сожалению, она установлена ​​не во всех системах :(. - person Kaleb Pederson; 16.01.2010
comment
@BryanH: ?? Это не Википедия, поэтому я не уверен в причине вашего мультфильма xkcd. Думаю, я пытался донести мысль (думаю, это было около 18 месяцев назад), что сам sed не может переименовывать файлы - для этого вам потребуются дополнительные сценарии. - person Simon Nickerson; 09.06.2011
comment
Могу подтвердить, что это работает с инструментом rename, установленным из brew (Mac). - person Husky; 08.01.2016

В Bash, который, скорее всего, будет вашей оболочкой входа по умолчанию, внешние команды не нужны.

shopt -s extglob
for i in 0*[^0]; do mv "$i" "${i##*(0)}"; done
person ephemient    schedule 15.01.2010

Может быть, не самый элегантный, но он будет работать.

for i in 0*
do
mv "${i}" "`expr "${i}" : '0*\(.*\)'`"
done
person jml3310    schedule 15.01.2010
comment
Над форматированием нужно поработать. Используйте 4 пробела перед for, чтобы сделать всю строку закодированной секцией. - person bradlis7; 16.01.2010

Попробуйте использовать sed, например:

sed -e 's:^0*::'

Полный цикл:

for f in `ls`; do
   mv $f $(echo $f | sed -e 's:^0*::')
done
person eduffy    schedule 15.01.2010
comment
Этого, вероятно, достаточно для ситуации Джорджа, но в другой среде можно было бы захотеть обработать особый случай, когда имя файла состоит из нулей. - person Jim Lewis; 16.01.2010
comment
Нет абсолютно никакой причины использовать for f in `ls` вместо гораздо более безопасного и эффективного for f in *. - person ephemient; 16.01.2010

Я вообще не знаю sed, но вы можете получить список, используя find:

find -type f -name *.jpg

так что с другим ответом это может выглядеть

find . -type f -name *.jpg | sed -e 's:^0*::'

но я не знаю, выдержит ли эта команда sed или нет.

person prodigitalson    schedule 15.01.2010

Вот тот, который не требует sed:

for x in *.jpg ; do let num="10#${x%%.jpg}"; mv $x ${num}.jpg ;  done

Обратите внимание, что это работает ТОЛЬКО, когда все имена файлов состоят из чисел. Вы также можете удалить ведущие нули с помощью оболочки:

for a in *.jpg ; do dest=${a/*(0)/} ; mv $a $dest ; done
person Kaleb Pederson    schedule 15.01.2010

В оболочке Bash вы можете сделать:

shopt -s nullglob
for file in 0*.jpg
do
   echo mv "$file" "${file##*0}"
done
person ghostdog74    schedule 15.01.2010

person    schedule
comment
Вам не нужно (и не следует) использовать ls таким образом. Сделайте это так: for FILE in * - person Dennis Williamson; 16.01.2010
comment
это плохой пример. сначала используйте ls, а затем никогда не цитируйте свои переменные - person ghostdog74; 16.01.2010
comment
Я не вижу никаких проблем с использованием ls. Вы можете заменить ее на предложенную ниже команду find или любую другую команду. Поскольку это работает, я действительно не понимаю, какие у вас оправдания, кроме стилистических, что, когда дело доходит до однострочных сценариев оболочки, кажется немного бессмысленным. - person cyborg; 16.01.2010
comment
* будет делать правильно, ls иногда нет (например, если в имени файла есть пробел, этот скрипт не будет работать). - person Justin Smith; 17.01.2010
comment
Мой опыт не показал такого поведения. При самостоятельном указании списка элементы должны быть разделены разрывом строки. - person cyborg; 17.01.2010