2012-07-19 34 views
10

我希望打印奇数行(1,3,5,7 ..)而不做任何更改,但即使是行(2,4,6,8)处理也是以流水线开始的grep的。我想将所有内容写入新文件(奇数行没有任何改变,偶数行新值)。如何在bash中处理每隔一行

我知道如何打印每隔一行在AWK:

awk ' NR % 2 == 1 { print; } NR % 2 ==0 {print; }' file.fasta 

然而,对于偶数行,我不想使用{print; },但我想用我的grep管道代替。

建议将不胜感激。非常感谢。

+3

'== 1 {print;}'是多余的,只是'awk'NR%2'将打印奇数行' – Kevin 2012-07-19 12:22:41

+0

感谢所有的帮助! – Perlnika 2012-07-19 12:38:32

回答

8

如果你打算做一个从内AWK

awk 'NR % 2 {print} !(NR % 2) && /pattern/ {print}' file.fasta 

然而,如果你打算做更多的事情,然后,为chepner already pointer out,你确实可以管:简单grep,你可以用额外的步骤做掉,做AWK本身的过滤,如。例如:

awk 'NR % 2 {print} !(NR % 2) {print | "grep pattern | rev" }' file.fasta 
打开一个管道命令 "pattern | rev"(注意两边的引号),并打印输出重定向到它

。请注意,这种情况下的输出可能不像您所预期的那样;您将最终输出所有奇数行,然后输出管道命令(消耗偶数行)。


(针对您的意见)来计算在每个偶数行字符的数量,请尝试:

awk 'NR % 2 {print} !(NR % 2) {print length($0)}' file.fasta 
+0

谢谢。我即将计算偶数行中的字母数量。 – Perlnika 2012-07-19 12:25:11

+0

@Perlnika你可以在awk中使用'length'命令获得字符的数量。查看更新的答案。 – 2012-07-19 12:29:59

+0

@Perlnika,一些fasta文件可能包含像'-'或'X'这样的奇怪字符,但是您可能已经回答了OP所需的内容。 – Steve 2012-07-19 12:32:02

6

可以通过管道从里面awk直接:

awk ' NR % 2 == 1 { print; } NR % 2 ==0 {print | "grep -o [actgnACTGN] | wc -l"; }' file.fasta 

注意,但是,这并不会保留您输入文件的顺序。

(所选择的答案是手头的工作好,但我会在这里离开这个答案,因为管道print语句外部命令的例子。)

+0

谢谢,我已经用awk'NR%2 == 1 {print; } NR%2 == 0 {print | grep -o [actgnACTGN] | wc -l}'文件。fasta(为了统计字符数),但是有wc的问题,说明:awk:第1行:在wc处或附近的语法错误(这样我猜问题就在我的管道中:) – Perlnika 2012-07-19 12:22:34

+0

你是什么意思维持秩序? – Perlnika 2012-07-19 12:29:02

+0

@Perlnika他意味着你将最终输出所有奇数行,然后输出管道(消耗所有偶数行) – 2012-07-19 12:36:17

1

为了让您的管道输出出现,才能与AWK输出,需要在每次迭代时关闭管道。这当然是非常低效的。

awk 'BEGIN{ cmd = "grep -io \047[actgn]\047 | wc -l" } NR % 2 { print } NR % 2 == 0 { print | cmd; close(cmd) }' file.fasta 

你显然不希望计算不在指定列表字符,所以length($0)将无法​​正常工作。这将工作,应该有很多比管道方法快:

awk 'NR % 2 { print } NR % 2 == 0 {n = split($0, a, /[^actgnACTGN]/); print length($0) - n + 1}' file.fasta 

它通过使用字符分割线你希望作为分隔符,并从长度减去子的数该行并添加1.实质上,它从行的长度中减去不需要的字符的数量,从而将所需字符的数量作为结果。