Linux xargs错误地将我的src dir复制到一个tgt目录

Linux xargs错误地将我的src dir复制到一个tgt目录,linux,bash,Linux,Bash,这个问题来源于一个简单的问题。我不想编辑前面的问题,因为这样我会给一个已经有很多评论的问题引入新的复杂性。这将扭曲当前答案的背景 下面是名为mapping.txt的映射文件 src/a/ tgt/aye/ src/b tgt/b/ src/c/ tgt/c 源文件结构如下所示 /tmp/testzone/src/a/afile.txt /tmp/testzone/src/b/bfile.txt /tmp/testzone/src/c/cfile.txt 我们要做的第一件事是基于map

这个问题来源于一个简单的问题。我不想编辑前面的问题,因为这样我会给一个已经有很多评论的问题引入新的复杂性。这将扭曲当前答案的背景

下面是名为
mapping.txt的映射文件

src/a/  tgt/aye/
src/b   tgt/b/
src/c/  tgt/c
源文件结构如下所示

/tmp/testzone/src/a/afile.txt
/tmp/testzone/src/b/bfile.txt
/tmp/testzone/src/c/cfile.txt
我们要做的第一件事是基于
mapping.txt
文件创建目标目录文件夹结构

cut -f 2 mapping.txt | tr '\n' '\0' | xargs -0 mkdir -p
这将创建目标目录文件夹结构

/tmp/testzone/tgt/aye/
/tmp/testzone/tgt/b/
/tmp/testzone/tgt/c/
接下来我们跑

 xargs --arg-file mapping2.txt cp -a
它似乎将源目录内容放入目标目录的
c
目录中。这是错误的。它应该使用
mapping.txt
文件逐行从源代码复制到目标代码

/tmp/testzone/tgt/aye/
/tmp/testzone/tgt/b/
/tmp/testzone/tgt/c/a/afile.txt
/tmp/testzone/tgt/c/aye/
/tmp/testzone/tgt/c/b/bfile.txt
/tmp/testzone/tgt/c/c/cfile.txt

导致此问题的原因是什么?

在没有其他指示选项的情况下,
xargs
会将输入文件中尽可能多的行作为参数放入单个
cp
调用中。这就是
xargs
的设计目的

您可能会找到一种方法来推动它朝着正确的方向发展,但这看起来就像您应该做的那样

while read -r src dst; do
    mkdir -p "${dst%/*}"
    cp -a "$src" "$dst"
done<mapping2.txt
读取时-r src dst;做
mkdir-p“${dst%/*}”
cp-a“$src”“$dst”

完成对于
xargs
,每个输入数据项都具有相同的“含义”--该工具设计用于对所有这些项执行相同的操作

您的输入数据项不符合该假设。
mappings.txt
文件包含一个源目录,然后是目标目录,然后是源目录,依此类推

因此,您要么需要使用不同的工具/脚本(如tripleee的回答中所建议的),要么需要修剪输入数据,使其符合“相同项目”的假设

修剪将要求您的输入项表示成对的(源、目标)目录。这样做的“黑客”是告诉
xargs
只有换行符(而不是任何空格)分隔项目。此外,由于
cp
命令的性质,每个输入对必须单独处理,一次一个。下面应该可以做到这一点:

xargs --arg-file mapping.txt --delimiter '\n' --max-args 1 -I PAIR sh -c "cp PAIR"

将输入
字符串单独调用
sh
会将输入对拆分为两个单独的单词,因此它们可以用作
cp

的输入。这与您不久前提出的一个问题有关。也许你应该更新你的其他问题,以显示哪些问题不起作用,而不是发布另一个问题。这个,呃,不是真的复制品。为什么我要给一个已经有这么多评论的问题引入新的复杂性?这会扭曲答案的上下文……也许你真的在寻找@iamauser,我同意OP的决定,发布一个单独的问题。在收到多个实质性答案后,强烈建议不要在堆栈溢出问题上更新具有新要求的问题。@tripleee从同一用户处看到: