【问题标题】:Write a for loop for simple awk command (linux)为简单的 awk 命令编写一个 for 循环(linux)
【发布时间】:2015-02-14 09:43:30
【问题描述】:

问题: 我正在尝试在文件(物种)中查找多个特定行,然后仅将每个物种名称后的第 5 行打印到新文件中。我可以单独为每个物种做这件事,但是我无法创建一个循环来遍历文档中的 1000 个物种中的每一个。 例如:

awk 'c&&!--c;/species_1$/{c=5}' results.out > speciesnames

我怎样才能使这个命令进入一个循环,以便它执行以下操作(迭代文件中的每个物种):

species 1,打印第 5 行以记录标题为speciesnames

species 2,打印第 5 行以记录标题为speciesnames

species n,打印第 5 行以记录标题为speciesnames

任何帮助将不胜感激。我对循环的经验很少。 谢谢

来自 results.out 的数据结构示例:

Query= species_1

length=341
Score
bits
Line 5, relevant info
description
description
description
description
description
description
description
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
nucleotides
data
data
data
data
data
data

Query= species_2

length=341

.......

所需的输出到文件种类名称:

Line 5, relevant info for species 1
Line 5, relevant info for species 2
Line 5, relevant info for species n

【问题讨论】:

  • 那是 results.out 的上下文吗?是否只需要打印第 5 行结果?
  • 上下文是每个物种都有大约 50 行与之相关的文本,但我只需要提取第 5 行。
  • “tr”命令可以跳行,并且具有循环功能。
  • 打印 descriptionnucleotides 20 次来尝试描述您的输入并不像显示一些实际数据那么有用。显示至少 3 个小块用于样本输入的代表性数据,一个用于 3 个不同物种中的每一个,每个块为 5 或 6 行。此外,根据该输入显示您想要的输出。

标签: linux loops awk


【解决方案1】:

我可能是这样的:

awk 'c&&!--c;/species_[0-9]+$/{c=5}' file

awk '/species_[0-9]+/{a[NR+5]} {b[NR]=$0} END {for (i in a) print b[i]}' file

这将打印species命中后的所有第5行。
对于array 的性质,awk 的输出是随机的。

新输入后调整代码:

awk 'c&&!--c;/species [0-9]+$/{c=4}' file
Line 5, relevent info

species 和数字之间没有_,而是一个空格。
你喜欢4,而不是5


示例数据:

cat file
Query= species 1
length=341
Score
bits
Line 5, relevent info
description
description
description
description
description
description
Query= species 5
length=341
Score
bits
Line 5, relevent info need this
description
description
description
description
description
Query= species 8
length=341
Score
bits
Line 5, relevent info more data
description
description
description
description
description
Query= species 6423
length=341
Score
bits
Line 5, relevent infom, yes here it is
description
description
description
description
description

awk 'c&&!--c {print i " --> " $0} /species [0-9]+$/{c=4;i=$2 FS $3}' file
species 1 --> Line 5, relevent info
species 5 --> Line 5, relevent info need this
species 8 --> Line 5, relevent info more data
species 6423 --> Line 5, relevent infom, yes here it is

最终解决方案:

awk 'c&&!--c;/species_/{c=5}' file

【讨论】:

  • 我试过这个,但只检索并打印了第一个物种:(
  • 您能否提供一些示例数据,并说明问题所在。如果不同 species 之间的距离小于 5 行,我会看到此操作失败
  • 我已更新我的问题以显示数据结构。
  • @user3237139 您需要使用代码标签{} 使您的帖子可读。我还是不明白你喜欢做什么。
  • 感谢您添加代码标签。对于每个物种,我想提取第五行。所以不要这样做: {awk 'c&&!--c;/species_1$/{c=5}' results.out > speciesnames} {awk 'c&&!--c;/species_2$/{c=5}' results .out > speciesnames} {awk 'c&&!--c;/species_3$/{c=5}' results.out > speciesnames} 直到我有所有物种的第五行,我只想找到一个循环会通过迭代来做到这一点。
【解决方案2】:

使用getline函数的方法

 awk '/^Query *= *species_[0-9]/{print $0":";for(i=1;i<=5;++i){if(getline>0 &&i==5){print}}}' file

开始循环并从匹配Query *= *species_[0-90]/的行中获取每5行

for(i=1;i<=5;++i)

到达第 5 行后打印

{if(getline>0 &&i==5){print}}}'

具有的示例文件

Query= species_1

length=341
Score
bits
Line 5, relevant info
description
description
data
data
data
data
data
data

Query= species_2

length=341
Score
bits
Line 5, relevant info
description
description
data
data
data
data
data
data

结果

Query= species_1:
Line 5, relevant info
Query= species_2:
Line 5, relevant info

【讨论】:

  • 您是否介意调整该脚本以显示如何在读取到 stderr 时打印每个输入行,以便我们可以看到脚本读取输入文件的每一行以进行调试?避免不必要地使用getline 的原因之一是它破坏了 awks 隐式读取循环的自然流程,因此使本来应该是微不足道的事情变得更难做,通常会导致重复代码或完全重写。见awk.info/?tip/getline
【解决方案3】:

你可以做一些类似的事情

linenr=0
species=unknown
cat results.out | while read -r line; do
   if [[ "${line}" = Query* ]]; then
      linenr=0
      species=$(echo ${line} | cut -d= -f2)
   else
      (( linenr = linenr + 1 ))
      if [ ${linenr} -eq 5 ]; then
         echo ${line} > ${species}.out
      fi
   fi
done

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-11-07
    • 1970-01-01
    • 1970-01-01
    • 2014-01-26
    • 1970-01-01
    相关资源
    最近更新 更多