awk:如何每四行替换一个字符串?

时间:2013-08-14 14:37:16

标签: awk

我有一个文件,其中每四行是这样的:

  HISEQ15:454:D27KKACXX:6:2316:16241:100283 1:N:0:GTTTCG 

(对于那些感兴趣的人,这个文件包含DNA序列)

我需要删除空格后面的所有内容,除了空格后的第一个数字(在本例中为1),然后在字符串的开头和数字之间插入/,所以我明白了:

  HISEQ15:454:D27KKACXX:6:2316:16241:100283/1

我只知道Perl,并且我的文件将大于10GB,因此我希望你可以帮助你掌握你的知识。

3 个答案:

答案 0 :(得分:4)

这个怎么样?

awk 'BEGIN{OFS="/"} NR%4==1{$2=$2*1}1' file

使用NR%4==1,我们得到的所有行号都是4K + 1。在这些行中,我们执行{$2=$2*1},即将空格后的第二部分转换为数字。然后使用{}1打印所有行。 为了使记录以“/”分隔,我们使用BEGIN{OFS="/"}部分,因为OFS代表“输出字段分隔符”。

请注意,条件NR%4==1可能会根据要更改的字符串的位置而更改。如果它是第1,第5,第9 ......那就好了。如果它是第2,第6 ......然后是NR%4==2,依此类推。

测试

$ cat a
HISEQ15:454:D27KKACXX:6:2316:16241:100283 1:N:0:GTTTCG 
a
b
d
HISEQ15:454:D27KKACXX:6:2316:16241:100283 7:N:0:GTTTCG 
ad
f
d
HISEQ15:454:D27KKACXX:6:2316:16241:100283 9:N:0:GTTTCG 
$ awk 'BEGIN{OFS="/"}NR%4==1{$2=$2*1}5' a
HISEQ15:454:D27KKACXX:6:2316:16241:100283/1
a
b
d
HISEQ15:454:D27KKACXX:6:2316:16241:100283/7
ad
f
d
HISEQ15:454:D27KKACXX:6:2316:16241:100283/9

答案 1 :(得分:3)

您可以使用执行此操作,我认为它更清晰:

sed 's! \([0-9]\).*!/\1!;n;n;n;' input

使用

awk 'NR%4==1 { $0=$1"/"substr($2,1,1); }1' input

答案 2 :(得分:1)

我认为Perl程序不需要更长时间才能执行此操作,除非您使用for循环来浏览文件。 (这将在任何处理发生之前加载整个文件。)无论您使用何种语言,主要瓶颈通常都是IO。

$ perl -pe 's( (\d).*){/$1} if $. % 4 == 1' filename

(很大程度上)相当于

while ( <ARGV> ) {
    s[ (\d).*][/$1] if $. % 4 == 1;
    print $_
}

如果您需要调整要修改的行,只需将1更改为需要的行 根据数据,您只需删除if $. % 4 == 1部分即可。 ($.是当前行号)

$ perl -pe 's( (\d).*){/$1}' filename

如果要就地修改文件,只需在命令中添加-i即可 如果您想要备份-i'.orig',也可以给-i一个参数。

$ perl -i -pe 's( (\d).*){/$1}' filename