【问题标题】:How to process every other line in bash如何处理bash中的每一行
【发布时间】:2021-04-17 03:45:54
【问题描述】:

我想打印奇数行 (1,3,5,7..) 而不做任何更改,但偶数行 (2,4,6,8) 处理以 grep 开头的管道。我想将所有内容写入新文件(奇数行没有任何更改,偶数行的新值)。

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

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

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

我们将不胜感激。非常感谢。

【问题讨论】:

  • ==1{print;} 是多余的,只是awk 'NR%2' will print odd lines

标签: bash awk


【解决方案1】:

如果您打算做一个简单的grep,您可以取消额外的步骤并在 awk 本身内进行过滤,例如:

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

但是,如果您打算做更多事情,就像chepner already pointed out,您确实可以从 awk 内部进行管道传输。例如:

awk 'NR % 2 {print} !(NR % 2) {print | "grep pattern | rev" }' file.fasta

这会打开一个到命令"grep pattern | rev" 的管道(注意周围的引号)并将打印输出重定向到它。请注意,这种情况下的输出可能与您预期的不同;您最终将首先输出所有奇数行,然后是管道命令的输出(消耗偶数行)。


(响应您的 cmets)计算每个偶数行中的字符数,尝试:

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

【讨论】:

  • 谢谢。我即将计算偶数行中的字母数。
  • @Perlnika 您可以使用 awk 中的length 命令获取字符数。查看更新的答案。
  • @Perlnika,一些 fasta 文件可能包含奇怪的字符,如 -X,但您可能已经回答了 OP 想要的内容。
  • @ShawnChin 非常感谢,我用 0 美元代替了 0 美元,它有效!
  • 对不起,有一个错字。应该是length($0)。答案已更新
【解决方案2】:

你可以直接从awk内部管道:

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

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

(选择的答案更适合手头的任务,但我将把这个答案留在这里作为将 print 语句传递给外部命令的示例。)

【讨论】:

  • 谢谢,我已经用 awk ' NR % 2 == 1 { print; } NR % 2 ==0 {打印 | grep -o [actgnACTGN] | wc -l }' file.fasta (为了计算行中的字母数)但是 wc 有问题说明:awk:第 1 行:wc 处或附近的语法错误(所以我猜问题出在我的管道中:)
  • 不保持秩序是什么意思?
  • @Perlnika 他的意思是你最终会首先输出所有奇数行,然后是管道输出(消耗所有偶数行)
  • 在我运行的简短测试中,打印了所有奇数行,然后是grep 输出的偶数行。这是因为 grep 的输出可能需要与 awk 的输出合并,这可能是不确定的。此外,这可能效率低下,因为我认为每个偶数行都会分叉一个单独的 grep
  • 对不起,我认为我已修复的引用中有一个错误。查看我的更新。
【解决方案3】:

为了使您的管道输出与 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。本质上,它减去了数字从行的长度中删除不需要的字符,结果是需要的字符数。

【讨论】:

    猜你喜欢
    • 2011-06-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-03
    • 1970-01-01
    • 2017-06-29
    • 1970-01-01
    • 2022-12-20
    • 1970-01-01
    相关资源
    最近更新 更多