0

我有一个像下面这样的文件

AT AT AG AG
GC GC GG GC

我想提取每个列的第一个和最后一个字符 n 将它们存储在两个不同的文件中

文件1:

A A A A
G G G G

文件2:

T T G G
C C G C

我的输入文件非常大。这是我可以在 awk 或 sed 中做到的方式吗

4

4 回答 4

2

使用 GNU awk 进行 gensub():

gawk '{
    print gensub(/.( |$)/,"","g") > "file1"
    print gensub(/(^| )./,"","g") > "file2"
}' file

您可以使用 gsub() 和几个变量在任何 awk 中执行类似操作。

于 2013-10-14T05:00:53.633 回答
1

你可以试试这个:

写在 test.awk

#!/usr/bin/awk -f

 BEGIN {

 #   FS = "[\s]+"
     outfile_head="file1"
     outfile_tail="file2"
 }

     {
         num = NF
         for(i = 1; i <= NF; i++) {
             printf "%s ", substr($i, 0, 1) >> outfile_head
             printf "%s ", substr($i, length($i), 1) >> outfile_tail
         }
     }

然后你运行这个: ./test.awk 文件

于 2013-10-14T02:03:19.460 回答
0

编辑 1:针对您的多行编辑进行了修改。

如果您打算编辑和共享它,您可以编写一个 perl 脚本并传入文件名。这只会遍历文件一次,并且不需要将文件存储在内存中。

文件“seq.pl”:

#!/usr/bin/perl

open(F1,">>$ARGV[1]");
open(F2,">>$ARGV[2]");
open(DATA,"$ARGV[0]");
while($line=<DATA>) {
  $line =~ s/(\r|\n)+//g;
  @pairs = split(/\s/, $line);
  for $pair(@pairs) {
    @bases = split(//,$pair);
    print F1 $bases[0]." ";
    print F2 $bases[length($bases)-1]." ";
  }
  print F1 "\n";
  print F2 "\n";
}
close(F1);
close(F2);
close(DATA);

像这样执行它:

perl seq.pl full.seq f1.seq f2.seq

文件“full.seq”:

AT AT AG AG
GC GC GG GC
AT AT GC GC

文件“f1.seq”:

A A A A
G G G G
A A G G

文件“f2.seq”:

T T G G
C C G C
T T C C
于 2013-10-14T02:01:08.917 回答
0

两遍很容易做到:

sed 's/\([^ ]\)[^ ]/\1/g' file > file1
sed 's/[^ ]\([^ ]\)/\1/g' file > file2

一次完成是一项挑战......

于 2013-10-14T01:35:44.040 回答