Linux 在被分隔符拆分的文件的每一行上,将Bash脚本转换为mkdir?
试图弄清楚如何逐行遍历Linux 在被分隔符拆分的文件的每一行上,将Bash脚本转换为mkdir?,linux,bash,xargs,Linux,Bash,Xargs,试图弄清楚如何逐行遍历.txt文件(filemappings.txt),然后使用选项卡(\t)作为分隔符拆分每一行,以便创建选项卡右侧指定的目录(mkdir-p) 读取filemappings.txt,然后按选项卡拆分每一行 server/ /client/app/ server/a/ /client/app/a/ server/b/ /client/app/b/ 会变成 mkdir -p /client/app/ mkdir -p /client/app/a/ mkdir -p /c
.txt
文件(filemappings.txt),然后使用选项卡(\t
)作为分隔符拆分每一行,以便创建选项卡右侧指定的目录(mkdir-p
)
读取filemappings.txt,然后按选项卡拆分每一行
server/ /client/app/
server/a/ /client/app/a/
server/b/ /client/app/b/
会变成
mkdir -p /client/app/
mkdir -p /client/app/a/
mkdir -p /client/app/b/
xargs
是一个好的选择吗?为什么
cut -f 2 filemappings.txt | tr '\n' '\0' | xargs -0 mkdir -p
xargs-0非常适合向量运算
sed -n '/\t/{s:^.*\t\t*:mkdir -p ":;s:$:":;p}' filemappings.txt | bash
sed-n
:仅使用包含选项卡(分隔符)的行
s:^.*\t\t*:mkdir-p:
:将所有内容从行行乞更改为选项卡
更改为mkdir-p
| bash
:告诉bash
创建文件夹
您已经有了一个答案,告诉您如何使用xargs
。根据我的经验,xargs
在您希望对易于检索的参数列表运行简单命令时非常有用。在您的示例中,xargs
会做得很好。但是,如果要执行比运行简单命令更复杂的操作,可能需要使用while
循环:
while IFS=$'\t' read -r a b
do
mkdir -p "$b"
done <filemappings.txt
通过这种方式,您可以读取多个参数以应用于任何一系列命令;一些xargs
不适合做的事情
使用read-r
将直接读取一行,而不考虑其中的任何反斜杠,以防您需要读取带有反斜杠的行
还请注意,某些操作系统可能允许选项卡作为文件或目录名的一部分。这将打破使用制表符作为参数分隔符的习惯。正如其他人所指出的,\t
字符也可能是文件或目录名的一部分,以下命令可能会失败。假设问题代表输入文件的真实形式,可以使用:
$ grep -o -P '(?<=\t).*' filemappings.txt | xargs -d'\n' mkdir -p
$grep-o-P'(?与GNU并行它看起来像这样:
parallel --colsep '\t' mkdir -p {2} < filemapping.txt
并行--colsep'\t'mkdir-p{2}
你的意思可能是-f2
?我想你可以使用xargs-d'\n'.
。我看不出把\n
转换成\0
然后使用xargs-0
(可能有什么区别?)@PesaThe:yeah-f1是个错误。我习惯性地将“\n”改为“\0”,而不知道这样做的原因。因为可能会指出,xargs
将以多个目录作为参数运行mkdir-p
。这很好,对于接受arbit的命令是一个很好的优化作为参数的文件名或目录名列表很少;但在其他一些场景中显然不太理想。对不起,链接错误;另一个问题是顺便说一句——文件名允许包含制表符(或换行符!),因此这不是一种用于完全任意名称的好文件格式;一般来说,不受信任的名称列表应始终以NUL分隔。xargs
在不创建太长命令行的情况下尽可能少地运行其命令,因此在Joshua的回答中,它将只运行一次mkdir
,而您的解决方案ion每行运行一次。另外,如果路径中有“
”,它将不起作用,并且可以用来执行任意代码!因此,有几件事值得一提。1)引用:“$b”
2)如果IFS=\t
将不起作用。您必须使用IFS=$'\t'
3)您正在为脚本的其余部分更改IFS
(这会把事情搞砸)。声明它只是为了read
cmd:IFS=$'\t'read…
4)read
不使用-r
会产生反斜杠。@PesaThe,我已经测试了我的答案,IFS=\t
对我有效。我也尝试过IFS=$'\t'
但对我无效。你是对的,为一条语句定义变量是正确的,但我已经用而语句a尝试过了它对我不起作用。关于$b
的引号,你完全正确。修复了,谢谢。@PesaThe,在正确的位置测试了IFS=$'\t'
,现在它工作了…:-)我也修复了。正如你所说,在脚本的其余部分更改IFS
并不理想。再次感谢。IFS=\t
不应该在拆分时工作关于文字>代码> t>代码>字符:请参见此。最后注意:考虑添加<代码> -r>代码>选项,以便允许包含反斜杠的DRE。@ PesaThe,接受接受,谢谢!我已经更改了解释,包括<代码> -r>代码>选项。您是对的。<代码> -d′\n′/COD>确实具有大量的输入行。D
parallel --colsep '\t' mkdir -p {2} < filemapping.txt