Команда Shell для форматирования чисел внутри имен файлов

У меня есть папка, содержащая следующие файлы:

trackingData-00-1.data, trackingData-00-2.data, ..., trackingData-00-2345.data

И я хотел бы переименовать их, форматируя числа с 4 цифрами

trackingData-00-0001.data, trackingData-00-0002.data, ..., trackingData-00-2345.data

Как я могу достичь этого с помощью команды bash shell?

2

4 ответы

Чистое решение bash :

for f in trackingData-00-*.data; do
    [[ $f =~ trackingData-00-([0-9]+).data ]]
    mv "$f" $(printf "trackingData-00-%04d.data" ${BASH_REMATCH[1]})
done

Регулярное выражение извлекает число для ввода и сохраняет его в массиве BASH_REMATCH . Затем printf используется для создания нового имени файла, с повторным вводом и дополнением нулями.

6
добавлено

Вы можете использовать опции printf в awk для печати четырех цифр:

echo 3 | awk '{printf ("%04i", $1)}'
0003
echo 33 | awk '{printf ("%04i", $1)}'
0033

Таким образом, это может быть:

for file in trackingData*
do
  num=$(awk -F[.-] '{printf ("%04i", $3)}' <<< "$file")
  mv $file trackingData-00-$num.data
done

Это использует awk с обоими разделителями полей: либо . , либо - . Затем он берет на себя 3-й блок и форматирует его значение с помощью флага % 04i (почти эквивалентного % d , как показано в Руководство пользователя GNU Awk # 5.5.2 Письма с форматным контролем ).

2
добавлено

грязный, но рабочий взлом:

for i in $(seq 2345); do
    mv trackingData-00-$i.data trackingData-00-`printf %04d $i`.data;
done
2
добавлено
что, если некоторые файлы в последовательности отсутствуют?
добавлено автор fiddler, источник
Вы можете добавить , если [[-f trackingData-00- $ i.data]] перед mv
добавлено автор glenn jackman, источник
Итак, вы получили предупреждение «Нет такого файла». Петля не ломается.
добавлено автор JIghtuse, источник

Прежде всего, я предполагаю, что в имени файла нет пробелов. тогда

ls/find...| awk -F'-|\\.' '{o=$0;$3=sprintf("%04d",$3);$4=".data";gsub(/-\./,".");print "mv "o" "$0}' OFS='-'

выведет команду mv ... . для их выполнения просто подключите вывод к sh , как

ls...|awk ..|sh

ядро - часть awk, немного протестируйте его:

kent$  echo "trackingData-00-1.data
trackingData-00-2.data"|awk -F'-|\\.' '{o=$0;$3=sprintf("%04d",$3);$4=".data";gsub(/-\./,".");print "mv "o" "$0}' OFS='-'                                                   
mv trackingData-00-1.data trackingData-00-0001.data
mv trackingData-00-2.data trackingData-00-0002.data
1
добавлено
добавлено автор glenn jackman, источник
pro.bash
pro.bash
123 участник(ов)

All about Nix shells, signals, processes and development in general.