Linux shell 脚本为文件名添加前导零

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3672301/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 20:26:22  来源:igfitidea点击:

Linux shell script to add leading zeros to file names

linuxbashshellgrep

提问by David Oneill

I have a folder with about 1,700 files. They are all named like 1.txtor 1497.txt, etc. I would like to rename all the files so that all the filenames are four digits long.

我有一个包含大约 1,700 个文件的文件夹。它们都命名为 like1.txt1497.txt等。我想重命名所有文件,以便所有文件名都是四位数。

I.e., 23.txtbecomes 0023.txt.

即,23.txt变成0023.txt

What is a shell script that will do this? Or a related question: How do I use grep to only match lines that contain \d.txt(i.e., one digit, then a period, then the letters txt)?

什么是可以执行此操作的 shell 脚本?或相关问题:如何使用 grep 仅匹配包含\d.txt(即,一位数字,然后是句点,然后是字母txt)的行?

Here's what I have so far:

这是我到目前为止所拥有的:

for a in [command i need help with]
do
  mv $a 000$a
done

Basically, run that three times, with commands there to find one digit, two digits, and three digit filenames (with the number of initial zeros changed).

基本上,运行 3 次,使用命令来查找一位、两位和三位文件名(初始零的数量已更改)。

采纳答案by Colin Hebert

Try:

尝试:

for a in [0-9]*.txt; do
    mv $a `printf %04d.%s ${a%.*} ${a##*.}`
done

Change the filename pattern ([0-9]*.txt) as necessary.

[0-9]*.txt根据需要更改文件名模式 ( )。



A general-purpose enumerated rename that makes no assumptions about the initial set of filenames:

通用枚举重命名,不假设初始文件名集:

X=1;
for i in *.txt; do
  mv $i $(printf %04d.%s ${X%.*} ${i##*.})
  let X="$X+1"
done


On the same topic:

关于同一主题:

回答by LukeN

To only match single digit text files, you can do...

要仅匹配一位数的文本文件,您可以执行...

$ ls | grep '[0-9]\.txt'

回答by Chris Jester-Young

for a in *.txt; do
  b=$(printf %04d.txt ${a%.txt})
  if [ $a != $b ]; then
    mv $a $b
  fi
done

回答by rkhayrov

One-liner:

单线:

ls | awk '/^([0-9]+)\.txt$/ { printf("%s %04d.txt\n", 
grep -E '^[0-9]\.txt$'
, ) }' | 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 仅匹配包含 \d.txt 的行(即 1 位数字,然后是句点,然后是字母 txt)?

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

回答by Paused until further notice.

Using the rename(prenamein 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.

使用有时随 Perl 安装的renameprename在某些情况下)脚本,您可以使用 Perl 表达式进行重命名。如果存在名称冲突,脚本将跳过重命名。

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.

下面的命令仅重命名具有四个或更少数字且后跟“.txt”扩展名的文件。它不会重命名不严格符合该模式的文件。它不会截断由超过四位数字组成的名称。

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

A few examples:

几个例子:

#!/bin/bash
num=0
for i in *.dat
do

  a=`printf "%05d" $num`
  mv "$i" "filename_$a.dat"
  let "num = $(($num + 1))"
done

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.

到目前为止给出的其他答案将尝试重命名不符合模式的文件,为包含非数字字符的文件名产生错误,执行产生名称冲突的重命名,尝试并失败重命名名称中包含空格的文件以及可能还有其他问题。

回答by sinner

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.shand then execute using ./run.sh:

假设您的文件夹中有数据类型为 .dat 的文件。只需将此代码复制到名为 run.sh 的文件中,通过运行使其可执行chmode +x run.sh,然后使用./run.sh以下命令执行:

while [ -f ./result/result`printf "%03d" $a`.txt ]; do a=$((a+1));done
RESULT=result/result`printf "%03d" $a`.txt

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

这将所有文件转换您的文件夹中filename_00000.datfilename_00001.dat等等。

回答by kayn

One-liner hint:

单行提示:

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

回答by rindeal

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.

此版本还支持在数字之前(之后)处理字符串。但基本上你可以做任何正则表达式匹配+printf,只要你的awk支持它。它也支持文件名中的空白字符(换行符除外)。

#!/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

回答by Charles Duffy

To provide a solution that's cautiously written to be correct even in the presence of filenames with spaces:

提供一个即使在存在带空格的文件名的情况下也谨慎编写正确的解决方案:

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

回答by Nico Rodsevich

There is a rename.ulcommand installed from util-linuxpackage (at least in Ubuntu) by default installed.

默认情况下,有一个rename.ulutil-linux包(至少在 Ubuntu 中)安装的命令。

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

它的用途是(做一个人 rename.ul):

rename [options] expression replacement file...

重命名 [选项] 表达式替换文件...

The command will replace the first occurrence of expressionwith the given replacementfor the provided files.

该命令将用提供的文件expression的给定替换第一次出现的replacement

While forming the command you can use:

在形成命令时,您可以使用:

rename.ul "" 000 ?.txt
rename.ul "" 00 ??.txt
rename.ul "" 0 ???.txt

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

因为没有做任何更改,而是阅读了该命令将进行的更改。如果确定只重新执行没有 -v(详细)和 -n(无行为)选项的命令

for your case the commands are:

对于您的情况,命令是:

##代码##