【问题标题】:awk to divide an individual file into multiple files with particular file namesawk 将单个文件分成具有特定文件名的多个文件
【发布时间】:2018-04-08 00:29:32
【问题描述】:

我有一个原始文件,其中包含以下特定格式的数据:

$ cat sample.txt
>MA0002.1   RUNX1
A  [    10     12      4      1      2      2      0      0      0      8     13 ]
C  [     2      2      7      1      0      8      0      0      1      2      2 ]
G  [     3      1      1      0     23      0     26     26      0      0      4 ]
T  [    11     11     14     24      1     16      0      0     25     16      7 ]
>MA0003.1   TFAP2A
A  [     0      0      0     22     19     55     53     19      9 ]
C  [     0    185    185     71     57     44     30     16     78 ]
G  [   185      0      0     46     61     67     91    137     79 ]
T  [     0      0      0     46     48     19     11     13     19 ]
>MA0003.3   TFAP2C
A  [  1706    137      0      0     33    575   3640   1012      0     31   1865 ]
C  [  1939    968   5309   5309   1646   2682    995    224     31   4726    798 ]
G  [   277   4340    139     11    658   1613    618   5309   5309    582   1295 ]
T  [  1386     47      0    281   2972    438     56      0      0     21   1350 ]

我想根据字母 > 将此文件分成单独的文件,我知道该字符每 5 行后出现一次。我可以这样做:

awk 'NR%5==1{x="F"++i;}{print > x}' sample.txt

问题是它可以正确创建多个文件,但文件名分别为 F1、F2 和 F3,并且没有任何扩展名。我想用它们第一行中提到的名称保存这些单独的文件,它们是RUNX1TFAP2ATFAP2C,扩展名为.pfm

因此最终文件将如下所示:

$ cat RUNX1.pfm
>MA0002.1   RUNX1
A  [    10     12      4      1      2      2      0      0      0      8     13 ]
C  [     2      2      7      1      0      8      0      0      1      2      2 ]
G  [     3      1      1      0     23      0     26     26      0      0      4 ]
T  [    11     11     14     24      1     16      0      0     25     16      7 ]

$ cat TFAP2A.pfm
>MA0003.1   TFAP2A
A  [     0      0      0     22     19     55     53     19      9 ]
C  [     0    185    185     71     57     44     30     16     78 ]
G  [   185      0      0     46     61     67     91    137     79 ]
T  [     0      0      0     46     48     19     11     13     19 ]

等等..

感谢您抽出时间来帮助我!

【问题讨论】:

    标签: file awk sed


    【解决方案1】:

    遵循 awk 可能会对您有所帮助。

    awk '/^>/{if(file){close(file)};file=$2".pfm"} {print > file".pfm"}'  Input_file
    

    在这里也添加一个带有解释的非单行表格。

    awk '
    /^>/{             ##Checking here if any line starts with ">" if yes then do following actions.
      if(file){       ##Checking if value of variable named file is NOT NULL, if condition is TRUE then do following.
        close(file)   ##close is awk out of the box command which will close any opened file, so that we could avoid situation of too many files opened at a time.
    };
      file=$2".pfm"   ##Setting variable named file to 2nd filed of the line which starts from ">" here.
    }
    {
    print > file".pfm"##Printing the value of current line to file".pfm" which will create file with $2 and .pfm name and put output into output files.
    }
    ' Input_file      ##Mentioning the Input_file name here.
    

    编辑:

    awk '/^>/{if(file){close(file)};array[$2]++;file=array[$2]?(array[$2]==1?$2:$2"."array[$2]):$2} {print > file".pfm"}'  Input_file
    

    【讨论】:

    • 这不会close甚至打开一个文件,因为你得到了file=$2并且你正在写file".pfm"file != file".pfm",使awk '/^>/{if(file)close(file); file=$2".pfm"}{print > file}' infile
    • 非常感谢您的详细解释。我这里有问题。有时同名使用 2 或 3 次。例如,有 3 行开头为:>MA0018.1 CREB1>MA0018.2 CREB1>MA0018.3 CREB1,在这种情况下只保存了 1 个文件。如果存在具有该名称的文件,则可以这样做,然后将它们保存为 name.1.pfm 和 name.2.pfm 等等。谢谢!
    • @Newbie,你能测试一次吗,我相信我测试了一个标签多次出现,它将这些行连接到同一个文件中,让我知道。
    • @Newbie,你的所有需求都应该出现在问题中,而不是分散在cmets中。
    • @RavinderSingh13 正如我之前所说,我看不出我已经接受了你的回答。我看不到那个绿色勾号,并认为这个问题仍然没有接受任何答案,因此,基于顶部的那个答案以及我对该答案的评论“这就是我真正想做的”,我接受了这个答案。
    【解决方案2】:

    就是这样

    awk -v RS=">" '{print RS$0 > $2".pfm"; close($2".pfm")}' file
    

    如果已经保存了同名文件,则要保存一个新文件,然后使用这个:

    awk -v RS=">" '{a[$2]++; if(a[$2]>1) file=$2"."a[$2]; else file=$2; print RS$0 > file".pfm" ; close(file".pfm")}' file
    

    例如。如果 TFAP2A.pfm 在之前保存,则新文件将保存为 TFAP2A.2.pfm TFAP2A.3.pfm .... 和以此类推

    或者简单

    awk -v RS=">" '{file=$2"."++a[$2]; print RS$0 > file".pfm" ; close(file".pfm")}' file
    

    如果您想使用版本 Ex 保存每个文件。 abc.1.pfm abc.2.pfm

    【讨论】:

    • 恕我直言,如果有很多文件,这可能会出现错误“打开的文件太多”,因此关闭(文件名)可以增加它的美感。
    • @RavinderSingh13:谢谢拉文德。做到了。 (y)
    • 非常感谢您的解决方案。我这里有问题。有时同名使用 2 或 3 次。例如,有 3 行开头为:>MA0018.1 CREB1、>MA0018.2 CREB1 和 >MA0018.3 CREB1,在这种情况下只保存了 1 个文件。如果存在具有该名称的文件,则可以这样做,然后将它们保存为 name.1.pfm 和 name.2.pfm 等等。谢谢!
    • @batMan Perfect.. 中间解决方案是我想要的解决方案。非常感谢!
    • @Newbie:你来了,伙计! stackoverflow.com/a/49537656/8300271
    【解决方案3】:

    awk 方法:

    awk 'NR%5==1{ fn=$2".pfm" }fn{ print > fn}' file
    

    或同样使用> 标记:

    awk '/^>/{ fn=$2".pfm" }fn{ print > fn}' file
    

    【讨论】:

    【解决方案4】:

    如果名称被多次使用,请注意以下一项

    单线:

    awk '/>/{f=$2 (a[$2]++?"."a[$2]-1:"") ".pfm"; if(f!=p){ close(p); p=f}}{print >f}' file
    

    更好的可读性:

     awk '/>/{
               f=$2 (a[$2]++?"."a[$2]-1:"") ".pfm"; 
               if(f!=p){ 
                    close(p); 
                    p=f
               }
              }
              {
                print >f
              }
         ' file
    

    输入:

    $ cat file
    >MA0002.1   RUNX1
    A  [    10     12      4      1      2      2      0      0      0      8     13 ]
    C  [     2      2      7      1      0      8      0      0      1      2      2 ]
    G  [     3      1      1      0     23      0     26     26      0      0      4 ]
    T  [    11     11     14     24      1     16      0      0     25     16      7 ]
    >MA0003.3   TFAP2C
    A  [  1706    137      0      0     33    575   3640   1012      0     31   1865 ]
    C  [  1939    968   5309   5309   1646   2682    995    224     31   4726    798 ]
    G  [   277   4340    139     11    658   1613    618   5309   5309    582   1295 ]
    T  [  1386     47      0    281   2972    438     56      0      0     21   1350 ]
    >MA0003.1   TFAP2A
    A  [     0      0      0     22     19     55     53     19      9 ]
    C  [     0    185    185     71     57     44     30     16     78 ]
    G  [   185      0      0     46     61     67     91    137     79 ]
    T  [     0      0      0     46     48     19     11     13     19 ]
    >MA0003.3   TFAP2C
    A  [  1706    137      0      0     33    575   3640   1012      0     31   1865 ]
    C  [  1939    968   5309   5309   1646   2682    995    224     31   4726    798 ]
    G  [   277   4340    139     11    658   1613    618   5309   5309    582   1295 ]
    T  [  1386     47      0    281   2972    438     56      0      0     21   1350 ]
    

    执行:

    $ awk '/>/{f=$2 (a[$2]++?"."a[$2]-1:"") ".pfm"; if(f!=p){ close(p); p=f}}{print >f}' file
    

    输出文件:

    $ ls *.pfm -1
    RUNX1.pfm
    TFAP2A.pfm
    TFAP2C.1.pfm
    TFAP2C.pfm
    

    每个文件的内容:

    $ for i in *.pfm; do echo "Output File:$i"; cat "$i"; done
    Output File:RUNX1.pfm
    >MA0002.1   RUNX1
    A  [    10     12      4      1      2      2      0      0      0      8     13 ]
    C  [     2      2      7      1      0      8      0      0      1      2      2 ]
    G  [     3      1      1      0     23      0     26     26      0      0      4 ]
    T  [    11     11     14     24      1     16      0      0     25     16      7 ]
    Output File:TFAP2A.pfm
    >MA0003.1   TFAP2A
    A  [     0      0      0     22     19     55     53     19      9 ]
    C  [     0    185    185     71     57     44     30     16     78 ]
    G  [   185      0      0     46     61     67     91    137     79 ]
    T  [     0      0      0     46     48     19     11     13     19 ]
    Output File:TFAP2C.1.pfm
    >MA0003.3   TFAP2C
    A  [  1706    137      0      0     33    575   3640   1012      0     31   1865 ]
    C  [  1939    968   5309   5309   1646   2682    995    224     31   4726    798 ]
    G  [   277   4340    139     11    658   1613    618   5309   5309    582   1295 ]
    T  [  1386     47      0    281   2972    438     56      0      0     21   1350 ]
    
    Output File:TFAP2C.pfm
    >MA0003.3   TFAP2C
    A  [  1706    137      0      0     33    575   3640   1012      0     31   1865 ]
    C  [  1939    968   5309   5309   1646   2682    995    224     31   4726    798 ]
    G  [   277   4340    139     11    658   1613    618   5309   5309    582   1295 ]
    T  [  1386     47      0    281   2972    438     56      0      0     21   1350 ]
    

    【讨论】:

    • 感谢您的回答,但它也将所有事件都写入同一个文件!
    • 你想增加文件??
    • 是的,每次出现都应单独存储,并在文件名中增加一个。例如,对于 CREB1.pfm,它将是 3 个文件,名称分别为 CREB1.1.pfm、CREB1.2.pfm 和 CREB1.3.pfm
    【解决方案5】:

    这可能对你有用(GNU sed 和 csplit):

    csplit -z file '/^>/' '{*}'
    sed -ns '1F;1s/^\S\+\s*//p' xx* | sed 'N;s/\n/ /;s/^/mv -v /e'
    

    使用 csplit 执行使用模式 ^> 拆分文件的工作,即在行首的 > 表示新文件。然后使用两次 sed 调用来重命名文件。第一个输出原始文件名及其预期名称。第二个添加并执行移动命令。将文件放在单独的目录中,并使用head * 查看结果。

    【讨论】:

      猜你喜欢
      • 2012-04-01
      • 2016-07-12
      • 2012-06-03
      • 1970-01-01
      • 2016-01-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多