【问题标题】:Change text in argument for xargs (or GNU Parallel)更改 xargs(或 GNU Parallel)的参数中的文本
【发布时间】:2012-03-30 03:02:49
【问题描述】:

我有一个可以以两种方式运行的程序:单端或双端模式。语法如下:

program <output-directory-name> <input1> [input2]

需要输出目录和至少一个输入。如果我想在三个文件上运行它,比如样本 A、B 和 C,我会使用 find with xargs 或 parallel 之类的东西:

user@host:~/single$ ls
sampleA.txt  sampleB.txt  sampleC.txt

user@host:~/single$ find . -name "sample*" | xargs -i echo program {}-out {}
program ./sampleA.txt-out ./sampleA.txt
program ./sampleB.txt-out ./sampleB.txt
program ./sampleC.txt-out ./sampleC.txt

user@host:~/single$ find . -name "sample*" | parallel --dry-run program {}-out {}
program ./sampleA.txt-out ./sampleA.txt
program ./sampleB.txt-out ./sampleB.txt
program ./sampleC.txt-out ./sampleC.txt

但是当我想在“paired-end”模式下运行程序时,我需要给它两个输入。这些是相关文件,但不能简单地将它们连接起来——您必须将两者都作为输入来运行程序。文件命名合理,例如 sampleA_1.txt 和 sampleA_2.txt。

我希望能够在命令行上使用 xargs(或最好是并行)之类的东西轻松创建它:

user@host:~/paired$ ls
sampleA_1.txt  sampleB_1.txt  sampleC_1.txt
sampleA_2.txt  sampleB_2.txt  sampleC_2.txt

user@host:~/paired$ find . -name "sample*_1.txt" | sed/awk? | parallel ?
program ./sampleA-out ./sampleA_1.txt ./sampleA_2.txt
program ./sampleB-out ./sampleB_1.txt ./sampleB_2.txt
program ./sampleC-out ./sampleC_1.txt ./sampleC_2.txt

理想情况下,该命令会删除 _1.txt 以创建输出目录名称(sampleA-out 等),但我确实需要能够接受该参数并将 _1 更改为 _2 以用于第二个输入.

我知道这对脚本来说非常简单——我在 Perl 中使用快速正则表达式替换来完成此操作。但我希望能够用一个快速的单线来做到这一点。

提前致谢。

【问题讨论】:

    标签: bash sed awk parallel-processing xargs


    【解决方案1】:

    假设您的目录中每对总是正好有 2 个文件,并假设它们按find 正确排序(这可以通过findsort 的管道结果来确保),可能是xargs -l 2会做的工作。这告诉xargs 在它执行的每个命令行上放置 2 个连续的传入参数。

    【讨论】:

      【解决方案2】:

      我在 Perl 中通过快速的正则表达式替换来做到这一点。但我希望能够用一个快速的单线来做到这一点。

      Perl 也有单行代码,就像 sedawk 一样。你可以写:

      find . -name "sample*_1.txt" | perl -pe 's/_1\.txt$//' | parallel program {}-out {}_1.txt {}_2.txt
      

      (-e 标志的意思是“下一个参数是程序文本”;-p 标志的意思是“程序应该循环运行;对于每一行输入,将 $_ 设置为该行,然后运行程序,然后打印$_".)

      【讨论】:

      • 我最喜欢这个答案,因为它可以与 xargs 或并行互换。感谢您的提示,以及有关 -p 和 -e 正在做什么的解释。看起来我也可以用 sed 's/_1\.txt//g' 做同样的事情。现在看来很明显。谢谢。
      【解决方案3】:

      使用sedxargs,您可以执行以下操作:

      find . -name "sample*_1.txt" | sed -n 's/_1\..*$//;h;s/$/_out/p;g;s/$/_1.txt/p;g;s/$/_2.txt/p' | xargs -L 3 echo program
      

      即:sed 创建三个参数,xargs -L 3 用三个参数组成命令行。

      【讨论】:

        【解决方案4】:

        更短的版本:

        parallel --xapply program {1.}.out {1} {2} :::: <(ls *_1.txt) <(ls *_2.txt)
        

        但这只有在每个 _1.txt 都有一个匹配的 _2.txt 时才有效,反之亦然。

        【讨论】:

          猜你喜欢
          • 2014-07-19
          • 2016-10-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-04
          相关资源
          最近更新 更多