我想打印奇数行(1,3,5,7..)而不做任何更改,但偶数行(2,4,6,8)处理以grep开头的管道。我想将所有内容写入新文件(奇数行没有任何更改,偶数行的新值)。
我知道如何在 awk 中打印每一行:
awk ' NR % 2 == 1 { print; } NR % 2 ==0 {print; }' file.fasta
但是,对于偶数行,我不想使用{print; }
,但我想使用我的 grep 管道。
建议将不胜感激。非常感谢。
如果您打算做一个简单的grep
,您可以取消额外的步骤并在 awk 本身内进行过滤,例如:
awk 'NR % 2 {print} !(NR % 2) && /pattern/ {print}' file.fasta
但是,如果您打算做更多事情,正如chepner 已经指出的那样,您确实可以从 awk 内部进行管道传输。例如:
awk 'NR % 2 {print} !(NR % 2) {print | "grep pattern | rev" }' file.fasta
这会打开一个到命令的管道"grep pattern | rev"
(注意周围的引号)并将打印输出重定向到它。请注意,这种情况下的输出可能与您预期的不同;您最终将首先输出所有奇数行,然后是管道命令的输出(消耗偶数行)。
(响应您的评论)要计算每个偶数行中的字符数,请尝试:
awk 'NR % 2 {print} !(NR % 2) {print length($0)}' file.fasta
您可以直接从内部管道awk
:
awk ' NR % 2 == 1 { print; } NR % 2 ==0 {print | "grep -o [actgnACTGN] | wc -l"; }' file.fasta
但是请注意,这不会保留输入文件的顺序。
(选择的答案更适合手头的任务,但我将把这个答案留在这里作为将 print 语句传递给外部命令的示例。)
为了让您的管道输出与 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。本质上,它从离开的行的长度中减去不需要的字符数结果是想要的字符数。