如何在bash脚本中根据父文件夹名称重命名文件

时间:2018-01-23 06:58:27

标签: linux bash

我想根据父/子显示目录名重命名文件。

例如: test.xml文件位于

/usr/local/data/A/20180101
/usr/local/data/A/20180102
/usr/local/data/B/20180101

如何将/ usr / local / data / output中的test.xml文件保存为

A_20180101_test.xml
A_20180102_test.xml
b_20180101_test.xml

尝试编写如下脚本,但没有帮助。

#!/usr/bin/env bash

target_dir_path="/usr/local/data/output"

for file in /usr/local/data/*/*/test.xml; do
        l1="${file%%/*}"
        l2="${file#*/}"
        l2="${l2%%/*}"
        filename="${file##*/}"
        target_file_name="${l1}_${l2}_${filename}"
        echo cp "$file" "${target_dir_path}/${target_file_name}"
done

我在做错的任何事情都应该编写脚本吗?

3 个答案:

答案 0 :(得分:2)

我已经修改了一些代码以使其正常工作。请参阅代码中的注释

target_dir_path=""/usr/local/data/output"

for file in /usr/local/data/*/*/test.xml; do
    tmp=${file%/*/*/*}
    curr="${file#"$tmp/"}" # Extract wanted part of the filename
    mod=${curr//[\/]/_} # Replace forward slash with underscore
    mv "$file" "$target_dir_path$mod" # Move the file
done

答案 1 :(得分:2)

您可以使用以下命令执行此操作:

source_folder="usr/local/data/";target_folder="target"; find  $source_folder -type f -name test.xml | awk -v targetF=$target_folder 'BEGIN{FS="/"; OFS="_"}{printf $0" "; print targetF"/"$(NF-2),$(NF-1),$NF}' | xargs -n2 cp;

或在几行上为了可读性:

source_folder="usr/local/data/";
target_folder="target"; 
find  $source_folder -type f -name test.xml |\
awk -v targetF=$target_folder 'BEGIN{FS="/"; OFS="_"}{printf $0" "; print targetF"/"$(NF-2),$(NF-1),$NF}' |\
xargs -n2 cp;

其中

  • target_folder是您的目标文件夹
  • source_folder是您的源文件夹
  • find命令将搜索此源文件夹下存在的所有test.xml个命名文件
  • 然后awk命令将接收目标文件夹作为变量以便能够使用它,然后在BEGIN块中定义字段分隔符和输出字段分隔符,然后您只需打印初始文件名以及新文件名
  • 使用xargs将按2分组的结果输出传递给cp命令并完成技巧

<强> TESTED

enter image description here

<强> TODO:

您只需要将source_foldertarget_folder变量设置为环境中的内容,并最终将其放入脚本中,您就可以了!

答案 2 :(得分:1)

如果你有perl rename命令

$ for f in tst/*/*/test.xml; do
      rename -n 's|.*/([^/]+)/([^/]+)/(test.xml)|./$1_$2_$3|' "$f"
  done
rename(tst/A/20180101/test.xml, ./A_20180101_test.xml)
rename(tst/A/20180102/test.xml, ./A_20180102_test.xml)
rename(tst/B/20180101/test.xml, ./B_20180101_test.xml)
  • -n选项适用于干运行,测试后将其删除
  • 为您的用例更改tst/usr/local/data.//usr/local/data/output/
  • .*/忽略文件路径
  • ([^/]+)/([^/]+)/(test.xml)捕获所需部分
  • $1_$2_$3根据需要重新安排