根据父文件名更改文件名

时间:2019-01-30 17:10:26

标签: bash

大家好,我有几个文件,例如:

/path1/path2/path3/M2/SPA_1/run_ok/single /path1/path2/path3/M2/SPB_2/run_ok/single /path1/path2/path3/M2/SPC_3/run_ok/single

,我想根据其父母的姓名更改run_ok的名称并获取:

/path1/path2/path3/M2/SPA_1/run_ok_SPA_1/single /path1/path2/path3/M2/SPB_2/run_ok_SPB_2/single /path1/path2/path3/M2/SPC_3/run_ok_SPC_3/single

有人有主意吗? 谢谢。

实际上首先要从以下位置提取SPA_1部分:

/path1/path2/path3/M2/SPA_1/run_Ok/single/

并将其放入sppname变量。 我尝试过:

file="/path1/path2/path3/M2/SPA_1/run_X/single/"; sppname=$(basename $(dirname "$file")); echo "$sppname"

然后我应该登门: SPA_1

但不起作用。 非常感谢你。

2 个答案:

答案 0 :(得分:2)

您可以通过将sed与反向引用结合使用来实现此目标:

for file in /path1/path2/path3/M2/*/*/*; 
do 
    mv $file `echo $file | sed 's/\(\/.*\/.*\/.*\/\)\(.*\)\/\(.*\)\/single/\1\3_\2\/single/'`; 
done;

\1\2\3分别替换为路径的第一部分,所需的文件名和目录。它们在模式中的\(\)之间是匹配的。

要了解向后引用,您可以使用此简单示例。 sed中的基本搜索命令是s/SEARCH/REPLACE/。请注意,这里我们正在处理目录,因此每个斜杠/都用反斜杠\/进行了转义:

echo $file | sed 's/\/path1\/path2\/path3\/M2\/\(.*\)\/single/\1/'; 

这将为您提供字符串的SPA_1部分。它与模式的这一部分\(.*\)相匹配,而在替换中为\1(匹配项1)

答案 1 :(得分:2)

您只需要重命名目录run_ok; run_ok的内容无关。

cd /path1/path2/path3/M2 &&
  for d in */; do
    [ -d "$d"/run_ok ] && mv -- "$d"/run_ok "$d"/"run_ok_$d"
  done