Linux shell script, чтобы добавить ведущие нули в имена файлов
У меня есть папка с около 1700 файлами. Все они называются как 1.txt
или 1497.txt
и т.д. Я бы хотел переименовать все файлы, чтобы все имена файлов были длиной четыре цифры.
I.e., 23.txt
становится 0023.txt
.
Что такое оболочка script, которая сделает это? Или связанный с этим вопрос: как использовать grep только для соответствия строкам, содержащим \d.txt
(т.е. Одну цифру, затем период, затем буквы txt
)?
Вот что я до сих пор:
for a in [command i need help with]
do
mv $a 000$a
done
В принципе, запустите это три раза, с командами там, чтобы найти одну цифру, две цифры и трехзначные имена файлов (с изменением числа начальных нулей).
Ответы
Ответ 1
Try:
for a in [0-9]*.txt; do
mv $a `printf %04d.%s ${a%.*} ${a##*.}`
done
При необходимости измените шаблон файла ([0-9]*.txt
).
Перечислимое переименование общего назначения, которое не делает предположений о начальном наборе имен файлов:
X=1;
for i in *.txt; do
mv $i $(printf %04d.%s ${X%.*} ${i##*.})
let X="$X+1"
done
В той же теме:
Ответ 2
Используя rename
(prename
в некоторых случаях) script, который иногда устанавливается с Perl, вы можете использовать выражения Perl для переименования. script пропускает переименование, если есть столкновение имен.
Приведенная ниже команда переименовывает только файлы с четырьмя или меньшими цифрами, за которыми следует расширение ".txt". Он не переименовывает файлы, которые не соответствуют этому шаблону. Он не усекает имена, состоящие из более чем четырех цифр.
rename 'unless (/0+[0-9]{4}.txt/) {s/^([0-9]{1,3}\.txt)$/000$1/g;s/0*([0-9]{4}\..*)/$1/}' *
Несколько примеров:
Original Becomes
1.txt 0001.txt
02.txt 0002.txt
123.txt 0123.txt
00000.txt 00000.txt
1.23.txt 1.23.txt
Другие приведенные до сих пор ответы будут пытаться переименовать файлы, которые не соответствуют шаблону, создавать ошибки для имен файлов, которые содержат нецифровые символы, выполнять переименования, которые создают конфликты имен, пытаться и не переименовывать файлы с пробелами в их имена и, возможно, другие проблемы.
Ответ 3
for a in *.txt; do
b=$(printf %04d.txt ${a%.txt})
if [ $a != $b ]; then
mv $a $b
fi
done
Ответ 4
Однострочник:
ls | awk '/^([0-9]+)\.txt$/ { printf("%s %04d.txt\n", $0, $1) }' | xargs -n2 mv
Как использовать grep только для соответствия строкам, содержащим \d.txt(идентификатор IE 1, затем период, затем буквы txt)?
grep -E '^[0-9]\.txt$'
Ответ 5
Предположим, что у вас есть файлы с datatype.dat в вашей папке. Просто скопируйте этот код в файл с именем run.sh, сделайте его выполнимым, запустив chmode +x run.sh
, а затем выполните с помощью ./run.sh
:
#!/bin/bash
num=0
for i in *.dat
do
a=`printf "%05d" $num`
mv "$i" "filename_$a.dat"
let "num = $(($num + 1))"
done
Это преобразует все файлы в вашу папку в filename_00000.dat
, filename_00001.dat
и т.д.
Ответ 6
Эта версия также поддерживает обработку строк до (после) числа. Но в основном вы можете использовать любое регулярное выражение + printf, пока ваш awk поддерживает его. И он поддерживает символы пробелов (кроме символов новой строки) в именах файлов.
for f in *.txt ;do
mv "$f" "$(
awk -v f="$f" '{
if ( match(f, /^([a-zA-Z_-]*)([0-9]+)(\..+)/, a)) {
printf("%s%04d%s", a[1], a[2], a[3])
} else {
print(f)
}
}' <<<''
)"
done
Ответ 7
Чтобы соответствовать только текстовым файлам с одной цифрой, вы можете сделать...
$ ls | grep '[0-9]\.txt'
Ответ 8
Однострочный намек:
while [ -f ./result/result`printf "%03d" $a`.txt ]; do a=$((a+1));done
RESULT=result/result`printf "%03d" $a`.txt
Ответ 9
Чтобы обеспечить решение, которое с осторожностью написано, должно быть правильным даже при наличии имен файлов с пробелами:
#!/usr/bin/env bash
pattern='%04d' # pad with four digits: change this to taste
# enable extglob syntax: +([[:digit:]]) means "one or more digits"
# enable the nullglob flag: If no matches exist, a glob returns nothing (not itself).
shopt -s extglob nullglob
for f in [[:digit:]]*; do # iterate over filenames that start with digits
suffix=${f##+([[:digit:]])} # find the suffix (everything after the last digit)
number=${f%"$suffix"} # find the number (everything before the suffix)
printf -v new "$pattern" "$number" "$suffix" # pad the number, then append the suffix
if [[ $f != "$new" ]]; then # if the result differs from the old name
mv -- "$f" "$new" # ...then rename the file.
fi
done