在同一文件夹终端脚本中复制具有相同名称的多个文件

时间:2013-02-14 16:15:07

标签: bash scripting copy rename

我有很多名称相同的文件,目录结构(简化)如下:

 ../foo1/bar1/dir/file_1.ps  
 ../foo1/bar2/dir/file_1.ps  
 ../foo2/bar1/dir/file_1.ps
 .... and many more

因为查看所有这些ps文件是非常低效的 各自的目录,我想将它们全部复制到另一个目录中,但包括 中的前两个目录的名称(与我的目的相关) 文件名。

我以前尝试过这样,但是我无法从哪里获取哪个文件 都是连续命名的:

#!/bin/bash -xv

cp -v --backup=numbered {} */*/dir/file* ../plots/; 

../plots是我复制它们的文件夹。但是,它们现在的形式为file.ps.~x~(x是一个数字),所以我摆脱了“.ps。〜*〜”并只留下ps扩展名:

rename 's/\.ps.~*~//g' *;
rename 's/\~/.ps/g' *;

然后,由于ps文件有时会有数百个点并且需要很长时间才能打开,我只是将它们转换为jpg。

for file in * ; do convert -density 150 -quality 70 "$file" "${file/.ps/}".jpg; done;

这不是一个真正有效的bash脚本,因为我必须手动更改目录。

我想最好的方法是从名称开头复制文件 包含在复制文件名中的前两个目录。

我最后怎么做?

2 个答案:

答案 0 :(得分:6)

如果您只有两个级别的目录,则可以使用

for file in */*/*.ps
do 
    ln "$file" "${file//\//_}"
done

这会覆盖每个ps文件,并将它们硬链接到当前目录,并将/替换为_。如果您打算编辑文件但不想更新原件,请使用cp代替ln

对于任意目录级别,您可以使用特定于bash的

shopt -s globstar
for file in **/*.ps
do 
    ln "$file" "${file//\//_}"
done

但是你确定需要将它们全部复制到一个目录吗?您可能可以使用yourreader */*/*.ps打开它们,这取决于您的读者可能会逐一浏览它们,同时仍然可以看到完整路径。

答案 1 :(得分:1)

您应该运行find命令并首先打印名称,如

find . -name "file_1.ps" -print

然后迭代它们中的每一个并执行/到' - '或任何其他字符(如

)的字符串替换
${filename/\//-}

一般语法为${string/substring/replacement}。然后,您可以将其复制到所需的目录。完整的脚本可以写成如下。尚未测试过(目前不在linux上),因此如果出现语法错误,可能需要调整代码;)

for filename in `find . -name "file_1.ps" -print`
do
     newFileName=${filename/\//-}
     cp $filename YourNewDirectory/$newFileName
done

如果要将上述脚本放在其他目录中,则需要将脚本放在同一根目录中或更改find​​命令以查找特定目录。

参考