man*_*oth 5 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
Run Code Online (Sandbox Code Playgroud)
由于通过转到相应的目录来查看所有这些ps文件是非常低效的,我想将它们全部复制到另一个目录中,但是包括前两个目录的名称(与我的目的相关的那些)在文件名中.
我之前尝试过这样,但是我无法从哪里获取文件,因为它们都是连续命名的:
#!/bin/bash -xv
cp -v --backup=numbered {} */*/dir/file* ../plots/;
Run Code Online (Sandbox Code Playgroud)
哪里../plots是我复制它们的文件夹.但是,它们现在的格式为file.ps.~x~(x是一个数字),所以我摆脱了".ps.〜*〜"并只留下ps扩展名:
rename 's/\.ps.~*~//g' *;
rename 's/\~/.ps/g' *;
Run Code Online (Sandbox Code Playgroud)
然后,由于ps文件有时会有数百个点并且需要很长时间才能打开,我只需将它们转换为jpg.
for file in * ; do convert -density 150 -quality 70 "$file" "${file/.ps/}".jpg; done;
Run Code Online (Sandbox Code Playgroud)
这不是一个真正有效的bash脚本,因为我必须手动更改目录.
我想最好的方法是从开头复制文件,并在复制的文件名中包含前两个目录的名称.
我怎么能做到这一点呢?
如果您只有两个级别的目录,则可以使用
for file in */*/*.ps
do
ln "$file" "${file//\//_}"
done
Run Code Online (Sandbox Code Playgroud)
这会覆盖每个ps文件,并将它们硬链接到当前目录,并将/s替换为_.如果您打算编辑文件但不想更新原件,请使用cp而不是ln.
对于任意目录级别,您可以使用特定于bash的
shopt -s globstar
for file in **/*.ps
do
ln "$file" "${file//\//_}"
done
Run Code Online (Sandbox Code Playgroud)
但是你确定需要将它们全部复制到一个目录吗?您可以打开它们yourreader */*/*.ps,这取决于您的读者可以让它们一个接一个地浏览它们,同时仍然可以看到完整的路径.