必须有一个简单的解决方案来解决我的问题,但我无法得到它。我在多个文件夹中有多个文件,其名称带有图案连续重复多次,如下所示:
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
我需要XYZ12
从文件名中删除除其中一种模式之外的所有模式,以获得以下结果:
20170223_LibError.log-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
答案1
A)寻找+名字(Perl rename
)解决方案:
find . -type f -name "*-XYZ12-XYZ12-*.gz" -exec prename 's/(-XYZ12)(\1)+/$1/g' {} \;
乙) 额外的巴什+寻找+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
C)此外,您可以sed
通过仅使用以下内容来避免在上述 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
答案2
答案3
和ksh93
:
for f in ~(N)*.log@(-+([^-]))\1*.log*; do
echo mv -- "$f" "${f/@(*.log)@(-+([^-]))+(\2)/\1\2}"
done
(高兴时删除echo
)。
~(N)
: 该模式的 nullglob@(...)
: 分组(这样我们就可以将匹配的内容引用为\1
.+(...)
: 一项或多项...
。- So后面
*.log@(-+([^-]))\1*.log*
跟着*.log
重复-<non-hyphens>
的*.log*
。 ${f//pattern/replacement}
: 模式替换运算符。
因此将替换:whatever.log-repeat-repeat-repeatwhatever.log
为whatever.log-repeatwhatever.log
.
也可以看看那里有关 shell glob 中的反向引用支持的更多信息。
答案4
最简单的方法是删除XYZ12-
第一个实例并将第一个替换-
为-XYZ12-
:
$ echo 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 | sed -E 's,XYZ12-,,g' | sed 's,-,-XYZ12-,'
20170223_LibError.log-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
编辑:如果您事先不知道,XYZ12
可以使用 来提取它cut
。例如,创建do.sh
如下脚本:
#!/usr/bin/env sh
pattern=$(echo "$1" | cut -d- -f2)
echo "$1" | sed -E "s,$pattern-,,g" | sed "s,-,-$pattern-,"
用法:
$ ./do.sh 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-XYZ12-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
20170223_LibError.log-XYZ12-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
还有另一种模式:
$ ./do.sh 20170223_LibError.log-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-NMNM-SAE066.log_compressed_at_2017-09-27_03-32-55.gz
20170223_LibError.log-NMNM-SAE066.log_compressed_at_2017-09-27_03-32-55.gz