繁体   English   中英

如何在bash脚本中基于父文件夹和子文件夹的名称重命名文件

[英]How to rename file based on parent and child folder name in bash script

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

例如:位于以下位置的test.xml文件

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

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

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

我在这个脚本中做错什么了吗?

我已经对您的代码进行了一些修改以使其正常工作。 查看代码中的注释

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

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

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 bloc中定义字段分隔符和输出字段分隔符,然后只打印初始文件名和新文件名
  • 您使用xargs将按2分组的结果输出传递给cp命令,并且完成了窍门

已测试

在此处输入图片说明

去做:

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

如果您有基于perlrename命令

$ 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根据需要重新安排

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM