【问题标题】:Use an awk loop to subset a file使用 awk 循环对文件进行子集化
【发布时间】:2013-11-12 12:43:09
【问题描述】:

我有一个包含大量信息的文件,我想在第一列拆分。

示例(example.gen):

1 rs3094315 752566 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
1 rs2094315 752999 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
2 rs3044315 759996 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
2 rs3054375 799966 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
2 rs3094375 999566 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
3 rs3078315 799866 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
3 rs4054315 759986 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
4 rs4900215 752998 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
4 rs5094315 759886 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
4 rs6094315 798866 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1

期望的输出:

Chr1.gen

1 rs3094315 752566 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
1 rs2094315 752999 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1

Chr2.gen

2 rs3044315 759996 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
2 rs3054375 799966 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
2 rs3094375 999566 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1

Chr3.gen

3 rs3078315 799866 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
3 rs4054315 759986 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1

Chr4.gen

4 rs4900215 752998 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
4 rs5094315 759886 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
4 rs6094315 798866 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1

我尝试使用以下 shell 脚本执行此操作,但它不起作用 - 我无法弄清楚如何让 awk 识别在 awk 脚本本身之外定义的变量。

第一次脚本尝试(没有 awk 循环):

for i in {1..23}
do
    awk '{$1 = $i}' example.gen > Chr$i.gen
done   

第二次脚本尝试(使用 awk 循环):

for i in {1..23}
do
    awk '{for (i = 1; i <= 23; i++) $1 = $i}' example.gen > Chr$i.gen
done   

我确定它可能很基本,但我就是无法解决...

谢谢!

【问题讨论】:

    标签: shell loops awk


    【解决方案1】:

    使用 awk:

    awk '{print > "Chr"$1".gen"}' file
    

    它只是打印并将其重定向到一个文件。这个文件是如何定义的?与"Chr" + first_column + ".gen"

    使用您的示例输入,它会创建 4 个文件。比如第四个是:

    $ cat Chr4.gen 
    4 rs4900215 752998 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
    4 rs5094315 759886 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
    4 rs6094315 798866 A G 0 1 0 1 0 0 1 0 0 0 1 0 0 1
    

    【讨论】:

      【解决方案2】:

      首先,使用@fedorqui 的答案,因为这是最好的。但要了解您第一次尝试时犯的错误(很接近),请继续阅读。


      您的第一次尝试失败了,因为您将测试放在动作中(在大括号中),而不是在它之前。最小的修复:

      awk "\$1 == $i" example.gen > Chr$i.gen
      

      这使用双引号来允许i 的值被awk 脚本看到,但这需要您为$1 转义美元符号,这样您就不会替换shell 的第一个位置参数。更干净但更长:

      awk -v i=$i '$1 == i' example.gen > Chr$i.gen
      

      这会在awk 脚​​本内创建一个变量i,其值与shell 的i 变量相同。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-08-09
        • 1970-01-01
        • 1970-01-01
        • 2021-12-03
        • 2018-04-26
        • 2017-01-26
        • 1970-01-01
        • 2015-06-20
        相关资源
        最近更新 更多