我想根据父/子显示目录名重命名文件。
例如: 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
我在做错的任何事情都应该编写脚本吗?
答案 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
块中定义字段分隔符和输出字段分隔符,然后您只需打印初始文件名以及新文件名cp
命令并完成技巧<强> TESTED 强>:
<强> TODO:强>
您只需要将source_folder
和target_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
根据需要重新安排