重命名多个文件,删除模式的一个实例以外的所有文件

God*_*vil 4 bash sed awk rename

我的问题必须有一个简单的解决方案,但我无法解决。我在多个文件夹中有多个文件,其名称具有连续多次重复的模式,如下所示:

20170223_LibError.log-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
Run Code Online (Sandbox Code Playgroud)

我需要XYZ12从文件名中删除除一种模式之外的所有模式,以获得以下结果:

20170223_LibError.log-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
Run Code Online (Sandbox Code Playgroud)

Rom*_*est 6

a ) find + prename (Perl rename) 解决方案:

find . -type f -name "*-XYZ12-XYZ12-*.gz" -exec prename 's/(-XYZ12)(\1)+/$1/g' {} \;
Run Code Online (Sandbox Code Playgroud)

b )如果不支持额外的bash + find + sed方法prename

for f in $(find . -type f -name "*-XYZ12-XYZ12-*.gz"); do 
    p="${f%/*}"      # full path without basename (parent folders)   
    fn="${f##*/}"    # current filename (basename)
    new_fn=$(sed 's/\(-XYZ12\)\+/-XVZ12/' <<<"$fn")  # new file name
    mv "$f" "$p/$new_fn"
done
Run Code Online (Sandbox Code Playgroud)

c ) 此外,您可以sed通过仅使用bash变量替换来避免在上述 bash 方法中使用:

shopt -s extglob
for f in $(find . -type f -name "*-XYZ12-XYZ12-*.gz"); do 
    p="${f%/*}"      # full path without basename (parent folders)   
    fn="${f##*/}"    # current filename (basename)
    new_fn="${fn/+(-XYZ12)/-XVZ12}"  # new file name
    mv "$f" "$p/$new_fn"
done
Run Code Online (Sandbox Code Playgroud)