如何在展平树结构的同时,bash复制目录/子目录中的所有文件(不包括列表中包含的文件)?
我有一个包含子目录和文件的目录(称为“源”)。使用bash,我需要将此目录及其每个子目录中的所有文件(仅文件,而不是目录)复制到不同的目录(称为“目的地”)。目录树不能维护/必须展平。只能复制文本文件(称为“excluded.txt”)中未包含的文件 源输入示例:如何在展平树结构的同时,bash复制目录/子目录中的所有文件(不包括列表中包含的文件)?,bash,tree,find,copy,rsync,Bash,Tree,Find,Copy,Rsync,我有一个包含子目录和文件的目录(称为“源”)。使用bash,我需要将此目录及其每个子目录中的所有文件(仅文件,而不是目录)复制到不同的目录(称为“目的地”)。目录树不能维护/必须展平。只能复制文本文件(称为“excluded.txt”)中未包含的文件 源输入示例: /home/source/AAA/file1.xyz /home/source/AAA/GGG/file2.xyz /home/source/BBB/file3.tuv /home/source/BBB/HHH/file4.tuv
/home/source/AAA/file1.xyz
/home/source/AAA/GGG/file2.xyz
/home/source/BBB/file3.tuv
/home/source/BBB/HHH/file4.tuv
/home/destination/file1.xyz
/home/destination/file2.xyz
/home/destination/file3.tuv
/home/destination/file4.tuv
目标输出示例:
/home/source/AAA/file1.xyz
/home/source/AAA/GGG/file2.xyz
/home/source/BBB/file3.tuv
/home/source/BBB/HHH/file4.tuv
/home/destination/file1.xyz
/home/destination/file2.xyz
/home/destination/file3.tuv
/home/destination/file4.tuv
复制文件后,四个以上的文件名(file1.xyz等)将添加到excluded.txt(每个文件名位于新行)。然后,这些文件将定期从目标目录中删除
如果再次执行bash脚本,并且源文件存在,则如果它们的文件名出现在excluded.txt文件中,则不应将它们复制到目标
由于维护了目录树结构,我尝试使用“cp”和“rsync”失败。我使用“查找”也失败了,因为在执行复制操作之前,我无法对照“excluded.txt”列表检查结果。
find
应该是用于递归搜索的工具
find /home/source -type f $(printf "! -name %s" "$(cat exclude.txt)") -exec cp -n {} /home/destination \;
说明:
:要搜索的根目录的路径。搜索是递归的find/home/source
:仅检索文件-键入f
:将写入$(printf”!-name%s“$(cat exclude.txt))
,列出要排除的所有文件-名称文件1-名称文件2…
:为每个找到的项执行的操作<代码>{}表示找到的项-exec cp-n{}/home/destination
while read -r line
do
name="$line"
exclude="$exclude ! -name \"$name\""
done < "/mnt/destination/exclude.txt"
cmd1="find \"/home/source\" -type f "
cmd2=" -exec cp -n {} \"/home/destination\" \;"
result=$cmd1$exclude$cmd2
eval $result
读取时-r行
做
name=“$line”
exclude=“$exclude!-name\“$name\”
完成
说明(计入@Aserre):
:检查exclude.txt中的每一行。“-r”标志导致反斜杠被视为行的一部分读取时-r行
:excluded.txt中的整行存储在名为“name”的新字符串中name=“$line”
:将存储exclude=“$exclude!-name\“$name\”
在名为“排除”的新字符串中。此字符串是要排除的所有文件的列表,每个文件前面都有-名称为“file1”-名称为“file2”-名称…
。每个引号前都需要反斜杠-名称
:将以下两个命令存储到名为“cmd1”的字符串中cmd1=
:要搜索的根目录的路径。搜索是递归的find/home/source
:仅检索文件-键入f
:为每个找到的项执行的操作。{}表示找到的项-exec cp-n{}/home/destination
:将上一个命令存储到名为“cmd2”的字符串中cmd2=
:连接所有3个字符串result=$cmd1$exclude$cmd2
:获取名为“result”的字符串并将其作为命令运行eval$result
$(printf“!-name%s”“$(cat exclude.txt)”的新输出
命令显示!-name file1.txt
,然后在下一行显示“file 2.txt”
。“file 2.txt”
应该与前面的!-name
在同一行。我一直在论坛中搜索解决方案,似乎比我预期的要难。有什么想法吗?