我想打印奇数行(1,3,5,7 ..)而没有任何改变,但偶数行(2,4,6,8)处理以grep开头的管道。我想把所有东西都写到新文件中(没有任何改变的奇数行和偶数行的新值)。
我知道如何在awk中打印所有其他行:
awk ' NR % 2 == 1 { print; } NR % 2 ==0 {print; }' file.fasta
然而,对于偶数行,我不想使用{print; }
但我想使用我的grep管道。
我们将不胜感激。非常感谢。
答案 0 :(得分:10)
如果您打算做一个简单的grep
,您可以取消附加步骤并在awk中进行过滤,例如:
awk 'NR % 2 {print} !(NR % 2) && /pattern/ {print}' file.fasta
但是,如果你打算做更多的事情,那么就像chepner already pointer out一样,你确实可以从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
答案 1 :(得分:7)
您可以直接从awk
内部管道输入:
awk ' NR % 2 == 1 { print; } NR % 2 ==0 {print | "grep -o [actgnACTGN] | wc -l"; }' file.fasta
但请注意,这不会保留输入文件的顺序。
(选择的答案对于手头的任务更好,但我会在这里留下这个答案作为将print语句传递给外部命令的示例。)
答案 2 :(得分: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.本质上,它减去数字从行的长度中留下不需要的字符,留下想要的字符数作为结果。