如何重命名多个文件名中的日期

如何重命名多个文件名中的日期

我的文件看起来像这样:

ABC_20210101.csv
ABC_20210101_imp.csv

我想将文件名中的日期更新为特定日期:

ABC_20201231.csv
ABC_20201231_imp.csv

我该如何替换这些文件名?

答案1

使用 GNU 并行:

ls | parallel mv {} '{= s/(.*)\d{8}/${1}20210131/ =}'

测试于:

this_123456789_file_19991231_some.thing

如果您无权在将要运行的系统上安装软件,您可以将 GNU Parallel 直接包含在脚本中:

parallel --embed > newscript.sh

答案2

bash可以将文件名分开并重新组合

#!/bin/bash
new="20201231"

for file in *.csv
do
    # Split the filename into its consituent parts
    if [[ "$a" =~ (.*)[0-9]{8}(_imp)?(\.csv)$ ]]
    then
        # Assemble a new filename
        dest="${BASH_REMATCH[1]}${new}${BASH_REMATCH[2]}${BASH_REMATCH[3]}"
        if [[ ! -f "$dest" ]]
        then
            # No destination so rename
            [[ -t 2 ]] && echo "Rename $file as $dest" >&2
            echo mv -f "$file" "$dest"    # Remove "echo" to action
        fi
    fi
done

这更容易,rename但并非所有系统都安装了它(删除-n或替换-v为操作):

new="20201231" rename -n 's/(.*)?[0-9]{8}(_imp)?(\.csv)$/$1$ENV{new}$2$3/' *.csv

如果没有bash或者renamesed可以用来生成必要的目标文件名。可以说,这是更容易阅读的代码(除了 RE,它有许多反斜杠转义以满足 的sedERE 处理)

new="20201231"

for file in *.csv
do
    # Generate new filename
    dest=$(
        printf "%s\n" "$file" |
        sed -n 's/\(.*\)[0-9]\{8\}\(_imp\)\{0,1\}\(\.csv\)$/\1---\2\3/p'
    )

    if [ -n "$dest" ] && [ ! -f "$dest" ]
    then
        # Pattern substitued and target does not exist so rename
        [[ -t 2 ]] && echo "Rename $file as $dest" >&2
        echo mv -f "$file" "$dest"    # Remove "echo" to action
    fi
done

答案3

重命名文件的一种方法是首先使用 find 实用程序 abd 选择文件,然后将它们传递给 sed,它将构造新名称,然后 tgen 将一对传递给 xargs 以调用 mv 命令来进行重命名。

d0=19710110
d8=$(seq -f '[0-9%g]' 8 | paste -sd'\0')
find . -maxdepth 1 -type f \( -name "*_${d8}_imp.csv" -o -name "*_$d8.csv" \) -print |
sed -Ee "h;/_[0-9]{8}((_imp)?[.]csv)\$/s//_$d0\1/;x;G" |
xargs -r -d'\n' -n2 -t mv -i

答案4

标准 POSIX shshell 允许我们编写如下模式

./*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].csv

./*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_imp.csv

这些将与当前目录中您感兴趣的文件相匹配。 (显然,您可以使这些更具体,例如./*20[0-2][0-9][01][0-9][0-3][0-9].csv,这仍然允许匹配无效日期。)然后可以像这样重命名匹配这些模式的名称:

for name in ./*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].csv
do
    [ ! -e "$name" ] && continue
    newname=${name%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9].csv}20201231.csv
    mv "$name" "$newname"
done

for name in ./*[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_imp.csv
do
    [ ! -e "$name" ] && continue
    newname=${name%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]_imp.csv}20201231_imp.csv
    mv "$name" "$newname"
done

替换会从值的末尾${variable%pattern}删除匹配的字符串。pattern$variable

相关内容