使用for循环并将变量传递给命令

时间:2013-04-13 16:47:12

标签: unix grep

我有两个文件,table1.txt和table2.txt,第一列中的字符为chr1,chr2,chr3。我想迭代一个命令,使它从两个表中只包含chr1,chr2,chr3中的一个的行,并将该表的子集(比如chr1的所有行)传递给另一个命令(比如cat,它接受两个表作为输入)。然后输出保存为文件(比如new_chr1.txt用于chr1行的操作)。

以下是两个表的虚拟表示:

table1.txt:

chr1    5   55  1
chr1    14  62  1
chr1    47  97  1
chr2    4   52  1
chr2    20  70  1
chr2    25  75  1
chr3    3   52  1
chr3    6   56  1
chr3    10  60  1

table2.txt:

chr1    0       199
chr1    200     399
chr1    400     599
chr2    600     799
chr2    800     999
chr2    1000    1199
chr3    1200    1399
chr3    1400    1599
chr3    1600    1799

我尝试了以下代码:

for i in chr1 chr2 chr3
mkfifo table1
mkfifo table2
grep -w $i table1.txt > table1 &
grep -w $i table2.txt > table2 &
cat table1 table2 > new_$i.txt
done

从我的屏幕复制以下内容,以显示我在每个阶段获得的错误:

for i in chr1 chr2 chr3
mkfifo table1
-bash: syntax error near unexpected token `mkfifo'
mkfifo table2
grep -w $i table1.txt > table1 &
[5] 1969
grep -w $i table2.txt > table2 &
[6] 1970

cat table1 table2 > new_$i.txt
[5]   Exit 1                  grep -w $i table1.txt > table1
[6]   Exit 1                  grep -w $i table2.txt > table2
done
-bash: syntax error near unexpected token `done'

我无法弄清楚出了什么问题。如果我只运行上面的命令而没有for循环而没有mkfifo,并且通过指定要匹配的模式(比如chr1),它可以正常工作。知道如何使这项工作吗?

BTW,在我的实际代码中,我必须在两个cat ed文件上运行另一个命令,而不是grep

2 个答案:

答案 0 :(得分:2)

for循环需要do来启动循环体:

for i in chr1 chr2 chr3
do
    mkfifo table1
    mkfifo table2
    grep -w $i table1.txt > table1 &
    grep -w $i table2.txt > table2 &
    wait          # Make sure the grep commands are complete before using the results
    cat table1 table2 > new_$i.txt
done

可能还有其他问题,但这就是您遇到“-bash: syntax error near unexpected token `mkfifo'”错误的原因(而done错误是因为它认为您还没有for循环)。

顺便说一句,在循环中启动最终命令之前,您应该使用wait以确保grep操作已完成。

答案 1 :(得分:1)

您可以通过以下方式实现相同的目标:

for i in chr1 chr2 chr3
do
        grep -hw $i table[12].txt > new_$i.txt
done

它同时包含table1.txt和table2.txt。 -h阻止文件名在每行上打印。

如果您想单独执行这些操作,可以使用>>附加table2的输出:

grep -w $i table1.txt > new_$i.txt
grep -w $i table2.txt >> new_$i.txt