Linux shell script to add leading zeros to file names

后端 未结 10 1529
梦如初夏
梦如初夏 2020-12-04 06:43

I have a folder with about 1,700 files. They are all named like 1.txt or 1497.txt, etc. I would like to rename all the files so that all the filena

相关标签:
10条回答
  • 2020-12-04 07:18

    One-liner:

    ls | awk '/^([0-9]+)\.txt$/ { printf("%s %04d.txt\n", $0, $1) }' | xargs -n2 mv
    

    How do I use grep to only match lines that contain \d.txt (IE 1 digit, then a period, then the letters txt)?

    grep -E '^[0-9]\.txt$'
    
    0 讨论(0)
  • 2020-12-04 07:21

    Let's assume you have files with datatype .dat in your folder. Just copy this code to a file named run.sh, make it executable by running chmode +x run.sh and then execute using ./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
    

    This will convert all files in your folder to filename_00000.dat, filename_00001.dat, etc.

    0 讨论(0)
  • 2020-12-04 07:28

    There is a rename.ul command installed from util-linux package (at least in Ubuntu) by default installed.

    It's use is (do a man rename.ul):

    rename [options] expression replacement file...

    The command will replace the first occurrence of expression with the given replacement for the provided files.

    While forming the command you can use:

    rename.ul -nv replace-me with-this in-all?-these-files*
    

    for not doing any changes but reading what changes that command would make. When sure just reexecute the command without the -v (verbose) and -n (no-act) options

    for your case the commands are:

    rename.ul "" 000 ?.txt
    rename.ul "" 00 ??.txt
    rename.ul "" 0 ???.txt
    
    0 讨论(0)
  • 2020-12-04 07:29

    Using the rename (prename in some cases) script that is sometimes installed with Perl, you can use Perl expressions to do the renaming. The script skips renaming if there's a name collision.

    The command below renames only files that have four or fewer digits followed by a ".txt" extension. It does not rename files that do not strictly conform to that pattern. It does not truncate names that consist of more than four digits.

    rename 'unless (/0+[0-9]{4}.txt/) {s/^([0-9]{1,3}\.txt)$/000$1/g;s/0*([0-9]{4}\..*)/$1/}' *
    

    A few examples:

    Original    Becomes
    1.txt       0001.txt
    02.txt      0002.txt
    123.txt     0123.txt
    00000.txt   00000.txt
    1.23.txt    1.23.txt
    

    Other answers given so far will attempt to rename files that don't conform to the pattern, produce errors for filenames that contain non-digit characters, perform renames that produce name collisions, try and fail to rename files that have spaces in their names and possibly other problems.

    0 讨论(0)
  • 2020-12-04 07:33
    for a in *.txt; do
      b=$(printf %04d.txt ${a%.txt})
      if [ $a != $b ]; then
        mv $a $b
      fi
    done
    
    0 讨论(0)
  • 2020-12-04 07:38

    This version also supports handling strings before(after) the number. But basically you can do any regex matching+printf as long as your awk supports it. And it supports whitespace characters (except newlines) in filenames too.

    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
    
    0 讨论(0)
提交回复
热议问题