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