bash保留目录树中的递归复制文件

编程入门 行业动态 更新时间:2024-10-28 09:21:48
本文介绍了bash保留目录树中的递归复制文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我的应用程序X将项目组织在具有特定树的文件夹中。树的第一级被定义(硬约束),而所有内容都是自由组织的。

My application X organizes projects in folders with a specific tree. The first level of the tree is defined (hard constraint), while all the contents are freely organized.

我的目标是遍历项目树的所有文件夹,进行解析文件夹名称以根据条件获取目标,然后将选定的目标复制到新的项目文件夹中,并保留树结构,以使应用程序X不会抱怨。

My goal is to iterate over all folders of the project tree, parse folder names to get targets based on conditions, then copy the selected targets to a new project folder, keeping the tree structure, so that application X is not going to complain.

到目前为止,我已经提出了这个建议:

So far, I've come up with this:

cp -pr `find . -type d | grep -i targetstring` ../newProjectFolder/

这有问题:1)它不保留文件夹树; 2)引发很多错误 cp:无法统计(另请参见 时,无法在unix中统计错误,我会得到此错误)。

This has issues: 1) it doesn't preserve folder tree; 2) throws a lot of errors cp: cannot stat (see also this). It isn't just working as intended.

此外,解析 find 的输出是通常是个坏主意。

我能够用-父母,如建议在此处。但是,由于第2点,我的复制方式少于我需要的方式,因此毕竟不是解决方案。

I was able to overcome first problem with --parents as suggested here. However, I'm copying way less than what I need due to point 2, so not a solution after all.

我正在寻找一个该问题的一线解决方案 。您可以在此处获得基于脚本的解决方案。 编辑:,因为这被标记为所提供的链接的重复,所以我要重新措辞:我想要一个不需要在不需花时间的情况下明确解决的方法。通过管道查找和 grep 提供要复制的所有位置,但是 cp 正在抱怨。我们如何在不抱怨的情况下将它们喂入 cp ?

I am looking for a one-liner solution to the problem. Script based solution is available here. as this was marked as duplicated of the link provided, I'll rephrase a little: I want a solution where I don't need to explicitly while and if-else my way to it. Piping find and grep provides all the locations to be copied, but cp is complaining. How do we feed them to cp, without it complaining?

我在寻找使用 -exec 如建议的那样此处,并提出以下内容,该方法不起作用(什么都不会被复制)(仅复制部分树结构,并且仅在与regex匹配的情况下复制该结构中的文件,例如很好):

I was looking for something using -exec as suggersted here, and came up with the following, which is not working (nothing gets copied) (only partial tree structure is copied, and files inside that structure are only copied if they match the regex as well):

find . -regex ".*targetstring.*" -exec cp -rp --parents \{\} ../newProjectFolder \;

推荐答案

单线但 sed 不适用于文件名 $'\n'的换行符

"one-liner" but sed will not work for newlines $'\n' in filename

假设您 cd 进入项目文件夹并运行 find。始终与。 它将匹配 targetstring (在任何级别上),并从第一级别复制整个(包含)树>

assuming you cd into project folder and run find . always with . it will match targetstring (on any level) and will copy the whole (containing) tree from first level

示例树 searchProjectFolder / some / parent / folders / matched / targetstring / foo / bar /

在<$ c $中搜索 * targetstring * c> searchProjectFolder / 将复制整个 ./ some 文件夹(包括所有文件和子文件夹)

a search for *targetstring* inside searchProjectFolder/ will copy whole ./some folder (including all files and subfolders)

而 -regex 或 -ipath 将打印所有文件, -iname 仅会打印匹配的文件夹 targetstring / 本身。您可以使用 -mindepth 5 和 -maxdepth 5 将搜索限制到特定级别,并指定目标类型只能将文件夹与型d 匹配(但让我们暂时取消此选项)

while -regex or -ipath will print all files, -iname will only print the matching folder targetstring/ itself. you can limit search to specific level(s) with -mindepth 5 and -maxdepth 5, and specify the target type to match folders only with -type d (but let us take away this options for now)

创建newProjectFolder并在示例树上运行查找

mkdir newProjectFolder cd searchProjectFolder find . -iname "*targetstring*"

示例树的结果是

./some/parent/folders/matched/targetstring

现在查找结果通过管道传输到 grep ,因此我们可以将字符串剪切到第一级仅

now find result is piped to grep so we can cut the string to first level only

find . -iname "*targetstring*" | grep -o ^\./[^/]*

示例树的结果是

./some

代替 grep ,我们可以使用 sed 引用文件夹名称(可能有空格) )

instead of grep we can use sed to quote the "folder name" (may have spaces)

find . -iname "*targetstring*" | sed -n 's,^\(\./[^/]*\).*,"\1",p'

示例树上的结果是

"./some"

最后让我们 cp 所有 eval 因为引用了文件夹名称。这是单线:

finally let's cp all folders with eval because "folder names" are quoted. this is the "one-liner":

eval cp -a $(find . -iname "*targetstring*" | sed -n 's,^\(\./[^/]*\).*,"\1",p') ../newProjectFolder

示例树的结果是

cp -a "./some" ../newProjectFolder

为了更好的理解,我将解释sed

sed -n 's,^\(\./[^/]*\).*,"\1",p' sed -n 's, ^ \( \. / [^/]* \) .* , "\1" ,p'

-n =不打印输入 ,p'中的p =仅打印匹配的输出

-n = do not print input p in ,p' = print only matching output

\ 1 =打印第一个捕获组 \( =开始捕获组 \) =捕获组结束

\1 = print the first capture group \( = begin of capture group \) = end of capture group

^ =仅匹配字符串的开头 \。 =单点(。) / =单斜杠(路径分隔符) [^ /] =任何单个字节,但不是斜杠 [^ /] * =任何不包含斜杠的字符串 。 =单字节 。* =任何字符串

^ = match begin of string only \. = single dot (.) / = single slash (path delimiter) [^/] = any single byte, but not a slash [^/]* = any string not containing slashes . = single byte .* = any string

因此(第一个)捕获组是(行首) 。/example字符串

so the (first) capture group is (begin of line) ./example string

捕获组被引用( \1 ) 。/示例字符串

编辑:

如果只想复制文件夹 targetstring / (

another "real" one-liner if you only want to copy folder targetstring/ (with parent tree)

mkdir newProjectFolder cd searchProjectFolder find . -iname "*targetstring*" -exec cp -a --parents {} ../newProjectFolder \;

示例树的结果为

cp -a --parents "./some/parent/folders/matched/targetstring" ../newProjectFolder

更多推荐

bash保留目录树中的递归复制文件

本文发布于:2023-10-09 09:23:49,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1475350.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:递归   文件   目录   bash

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!