Подтвердить что ты не робот

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

В принципе, запустите это три раза, с командами там, чтобы найти одну цифру, две цифры и трехзначные имена файлов (с изменением числа начальных нулей).

4b9b3361

Ответ 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