我正在尝试编写一个脚本,循环遍历目录的所有子文件夹以搜索特定文件,然后将新文件复制到包含该文件的文件夹中。
这是我目前所拥有的:
#!/bin/sh
dir=/Documents
find "$dir" -name Sample.doc -printf "%p\n" | sort -nr | while read -r i; do
echo "$i"
done
这将列出文件夹Sample.doc
内的所有文件及其文件夹Documents
。
但是,我找不到从这些文件夹中提取路径以将新文件复制到其中的方法。
任何帮助,将不胜感激。
答案1
我认为您已经快到了。您可以%p
在表达式%h
中替换-printf
:
%h :文件名的前导目录(除最后一个元素外的所有元素)。如果文件名不包含斜杠(因为它在当前目录中),则 %h 说明符将扩展为“。”。
因此命令将会像这样:
find "$dir" -name Sample.doc -printf "%h\n" | sort -nr | while read -r i; do cp SomeFile "$i"; done
顺便问一下,为什么sort
需要这个部件?
答案2
该dirname
命令从完整路径中删除文件名
答案3
%h
另一个答案已经建议使用%p
,但我想添加一些改进以使您的代码更加健壮。例如,如果匹配的目录在其名称中包含换行符,则在最好的情况下,您最终会丢失目录并收到一些错误消息cp最糟糕的情况是,您可能会覆盖系统上任何地方的文件。
因此,请尝试这样做:
find "$dir" -name Sample.doc -printf "%h\0" | xargs --null -L1 cp SomeFile
ACSII 零保证永远不会出现在任何文件名中,因此与它不同,\n
它可作为传递路径的可靠分隔符。--null
指示xargs
使用\0
作为输入分隔符。然后它将对通过管道传递的每个项目执行一次给定的命令 ( cp Somefile
),同时将相应的项目作为附加参数附加。
答案4
在bash中:
shopt -s nullglob globstar
for i in "$dir"/**/Sample.doc
do
cp 'new file' "$(dirname "$i")"/
done
鱼类:
for i in $dir/**Sample.doc
cp 'new file' (dirname $i)/
end