【问题标题】:Bash - Filtering lines according to a conditionBash - 根据条件过滤行
【发布时间】:2018-04-05 02:53:01
【问题描述】:

我有一个文件,其中包含以下几行:

@SRR4293695.199563512 199563512 
CAAAANCATTCGTAGACGACCTGCTCTGTNGNTACCNTCAANAGATCNGAAGAGCACACGTCTGAACTCCAGTCAC
+SRR4293695.199563512 199563512 
A.AA<#FF)FFFFFFF<<<<FF7FFFFFF#.#<FF<#FFFF#FF<A<#FFFFFFFAFFFFFFAAAFFFFF<FFFF.
@SRR4293695.199563513 199563513 
CTAAANCATTCGTAGACGACCTGCTT
+SRR4293695.199563513 199563513 
<AAAA#FFFFFF<FFFFFFFFFFFFF
@SRR4293695.199563514 199563514 
CCAACNTCATAGAGGGACAAGTGGCGATCNGNC
+SRR4293695.199563514 199563514 
AAAAA#<F.F<<FA.F7AA.)<FAFA..7#.#A
@SRR4293695.199563515 199563515 
TCGCGNCCTCAGATCAGACGTGGCGA
+SRR4293695.199563515 199563515 
AAAAA#FFFFFF<FFFFFFFFFFFFF
@SRR4293695.199563516 199563516 
TGACCNGGGTCCGGTGCGGAGAGCCCTTC
+SRR4293695.199563516 199563516 
AAAAA#FAFFFF<F.FFAA.F)FFFFFAF
@SRR4293695.199563517 199563517 
AAATGNTCATCGACACTTCGAACGCACT
+SRR4293695.199563517 199563517 
AA)AA#F<FFFFFFAFFFFF<)FFFAFF
@SRR4293695.199563518 199563518 
TCGTANCCAATGAGGTCTATCCGAGGCGCN
+SRR4293695.199563518 199563518 
AAAAA#<FAAFFFF.FFFFFFFA.FFFFF#
@SRR4293695.199563519 199563519 
AAAACNATTCGTAGACGNCCTGCTTNTGTNGNCACCNTNANNANNTCNGNAGAGCNCACNTCTGAACTCNAGTCAC
+SRR4293695.199563519 199563519 
AAAAA#FFFFFFFFFFF#FFFFFFF#FF<#F#F.FF#7#F##F##A)#A#FF<F)#AAF#<FFFFAFF<#<FFFFF
@SRR4293695.199563520 199563520 
GAAGCNGCACAGCTGGCNTTGGAGCNGANNCNGTAGNCNCNNTNNATNGNTCGGNNGAGNACACGTCTGNACTCCA
+SRR4293695.199563520 199563520 
AAAAA#FFFFFFFFFFF#FFFFFFF#FF##A#FFFF#F#F##<##FF#F#FFFF##FFF#FFFFFFFFF#FFFFFF
@SRR4293695.199563521 199563521 
TGGTCNGTGGGGAGTCGNCGCCTGCNTANNANTGTANGNANNANNAANANATCGNNAGANCACACGTCTNAACTCC
+SRR4293695.199563521 199563521 
AAAAA#FFFFFFFFFFF#FFFFFFF#FF##F#FFFF#F#F##A##FF#A#FFFF##<FF#FFFFFFFFF#F<FFFF
@SRR4293695.199563522 199563522 
TCGTANCCAATGAGGTCTATCCGAGGCGCN
+SRR4293695.199563522 199563522
AAAAA#<FAAFFFF.FFFFFFFA.FFFFF#

然后,我想根据条件过滤这些行: 考虑偶数行的长度:如果该长度> 34,则必须删除该行和前一行。

我已经做了一个算法:使用一段时间来读取文件中的所有行,检查条件并只保留长度小于 34 的行。问题是它需要一些时间。

inputFile=$1 
outputFile=$2

while read first_line; read second_line
  do
    lread=${#second_line}
    if [[ "$lread" -le 34 ]] ; then
        echo $first_line >> $outputFile
        echo $second_line >> $outputFile
    fi
done < $inputFile 

# This is for the last two lines
lread=${#second_line}
if [[ "$lread" -le 34 ]] ; then
  echo $first_line >> $outputFile
  echo $second_line >> $outputFile
fi

我想知道是否有更快的方法。

预期输出:

@SRR4293695.199563513 199563513 
CTAAANCATTCGTAGACGACCTGCTT
+SRR4293695.199563513 199563513 
<AAAA#FFFFFF<FFFFFFFFFFFFF
@SRR4293695.199563514 199563514 
CCAACNTCATAGAGGGACAAGTGGCGATCNGNC
+SRR4293695.199563514 199563514 
AAAAA#<F.F<<FA.F7AA.)<FAFA..7#.#A
@SRR4293695.199563515 199563515 
TCGCGNCCTCAGATCAGACGTGGCGA
+SRR4293695.199563515 199563515 
AAAAA#FFFFFF<FFFFFFFFFFFFF
@SRR4293695.199563516 199563516 
TGACCNGGGTCCGGTGCGGAGAGCCCTTC
+SRR4293695.199563516 199563516 
AAAAA#FAFFFF<F.FFAA.F)FFFFFAF
@SRR4293695.199563517 199563517 
AAATGNTCATCGACACTTCGAACGCACT
+SRR4293695.199563517 199563517 
AA)AA#F<FFFFFFAFFFFF<)FFFAFF
@SRR4293695.199563518 199563518 
TCGTANCCAATGAGGTCTATCCGAGGCGCN
+SRR4293695.199563518 199563518 
AAAAA#<FAAFFFF.FFFFFFFA.FFFFF#
@SRR4293695.199563522 199563522 
TCGTANCCAATGAGGTCTATCCGAGGCGCN
+SRR4293695.199563522 199563522
AAAAA#<FAAFFFF.FFFFFFFA.FFFFF#

提前致谢!

【问题讨论】:

  • 你的代码在哪里?
  • ...somecommand... &gt;&gt; $outputFile 一遍又一遍地效率很低——当你把它单独放在每一行时,你的脚本每次想要附加一行时都会重新打开文件。相反,您应该只打开一次输出文件(例如,脚本顶部的exec &gt;"$outputFile" 将截断文件并使脚本中的所有未来标准输出重定向到它)。
  • 也就是说,如果您真的想要吞吐量,最好编写一个 awk 脚本而不是 bash(或者,如果您真的关心性能,请使用 Go 或Julia 在构建时就考虑到了这一点)。
  • 感谢您指出@CharlesDuffy。是的,我想写一个 awk 脚本,问题是我还不是专家。

标签: linux bash awk wc


【解决方案1】:

这是一个 awk 解决方案:

awk '!last { last = $0; next } length($0)<=34 { print last; print } { last = "" }' YOURFILE

输出是您的预期输出。

【讨论】:

  • 非常感谢!这正是我想要的!
【解决方案2】:

sed方法:

sed -n 'h;n;/.\{34,\}/!{x;G;p}' inputfile > outputfile
  1. h;n奇数行进入hold缓冲区,然后得到next行。
  2. 检查生成的偶数行的长度。如果它们超过 34 个字符,则保持缓冲区是 exchanged 与模式空间,然后附加到它, (x;G;),这样两行都在模式空间中,并且printed。

【讨论】:

    猜你喜欢
    • 2018-11-25
    • 2021-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2013-09-06
    相关资源
    最近更新 更多