【问题标题】:Cannot get bash to match whitespaces in a regular expression that is delimited by [[ ]] in an if satement无法让 bash 匹配 if 语句中由 [[ ]] 分隔的正则表达式中的空格
【发布时间】:2015-03-30 07:34:53
【问题描述】:

我正在开发一个简单的脚本来逐行读取文件,评估每一行的内容,并根据行号处理行数据。出于某种原因,我无法获得与空格匹配的正则表达式。 [:space:], [[:space:]], [:blank:], \s, \ , , 和 " " 都失败了。

我的数据格式如下(fastq格式):

    @SRR573708.2 2 length=100
    AAAACGTTAATATTTATTGAAATTGTT
    +SRR573708.2 2 length=100
    HHHHHHHHHHHHHHHHHHHHHHHHHHH

我想将其重新格式化为:

    @SRR573708.2/2
    AAAACGTTAATATTTATTGAAATTGTT
    +SRR573708.2/2
    HHHHHHHHHHHHHHHHHHHHHHHHHHH

然而,重要的是,在将其打印到新文件之前,我会检查每一行以确保其格式正确。我上次生成重新格式化文件的尝试在文件末尾产生了一些非常奇怪的结果。我的代码是:

    i=1
    while read LINE; do
        if (( $i > 4 )); then break; fi
        if (( $i % 4 == 1 )); then
            if [[ $data =~ ^@SRR[0-9]{6}[[:blank:]] ]]; then
                awk -v IFS=" " -v OFS="" -v ORS="" -v SUFFIX=$SUFFIX -v OUTPUT_FILE=$OUTPUT_FILE ' {print $1,SUFFIX,"\n"    } ' <<< $data
                i=$(( $i + 1 ))
            else
                echo -e "error at line ${i}"; echo "${data}"; exit 1; fi
        elif (( $i % 4 == 2 )); then echo -e "$LINE" 
            i=$(( $i + 1 ))

        elif (( $i % 4 == 3 )); then
            echo $data
            awk -v IFS=" " -v OFS="" -v ORS="" -v SUFFIX=$SUFFIX -v OUTPUT_FILE=$OUTPUT_FILE ' {print $1,SUFFIX,"\n"  } ' <<< $data
            i=$(( $i + 1 ))

elif (( $i % 4 == 0 )); then echo -e "$LINE" 
    i=$(( $i + 1 ))

else
    echo -e "number of liness is not divisible by 4. Program Terminated.\nProblem encountered at line ${i}."
    exit 1
fi

done < $INPUT_FILE

我收到错误消息:

    error at line 1
    @SRR573708.2 2 length=100

关于如何在正则表达式 if 语句中匹配空格的任何建议,最好只匹配空格和制表符而不是换行符。

【问题讨论】:

  • 您真的是指正好是一个[[:blank:]] 字符吗?也许你想要一个* 在它之后?还是你和.不匹配的问题?
  • 你的正则表达式匹配失败的原因是,在SRR[0-9]{6} 之后你有“.2”而不是空格。
  • read LINE 然后检查 $data。这是复制粘贴错误还是真的?
  • 请注意awk 是专门为“逐行读取文件,评估每行内容,并处理行数据”而设计的程序(在许多标准上,包括行号) .您可以很容易地将其转换为 1 个 awk 进程。祝你好运。
  • 注意:这个怪物awk -v IFS=" " -v OFS="" -v ORS="" -v SUFFIX=$SUFFIX -v OUTPUT_FILE=$OUTPUT_FILE ' {print $1,SUFFIX,"\n" } ' &lt;&lt;&lt; $data 可以更简单地写成echo "${data%% *}$SUFFIX",或者如果你愿意,可以写成echo "${data/ */$SUFFIX}"。 (我不确定你用 OUTPUT_FILE 做什么。)

标签: regex bash if-statement whitespace fastq


【解决方案1】:

一个工作的 awk 代码如下(虽然它不像 rici 的代码那样优雅和精简):

    awk -v i=1 -v IFS=" " -v OFS="" -v ORS="" -v SUFFIX=$SUFFIX -v OUTPUT_FILE=$OUTPUT_FILE -v nchars=0 -v DIRECTION=$DIRECTION ' {
        if (i%4==1 && $0~/^@SRR[0-9][0-9][0-9][0-9][0-9][0-9]\.[0-9]+\.$DIRECTION[[:blank:]][0-9]+[[:blank:]]length=100$/)
            { printf "%s%s\n",$1,SUFFIX >> OUTPUT_FILE; i++ }
        else if (i%4==2 && $0~/^[AGCTNagctn\-]+$/)
            { nchars=length($0);printf "%s\n",$1 >> OUTPUT_FILE;i++ }
        else if (i%4==3 && $0~/^\+SRR[0-9][0-9][0-9][0-9][0-9][0-9]\.[0-9]+[[:blank:]][0-9]+[[:blank:]]length=100$/)
            { printf "%s%s\n",$1,SUFFIX >> OUTPUT_FILE; i++}
        else if (i%4==0 && $0~/.*/ && nchars==length($0))
            { printf "%s\n",$1 >> OUTPUT_FILE;i++}
        else
            {printf "error at line %s:\n%s\n\n",i,$0; exit 1}
        }' $INPUT_FILE

【讨论】:

    猜你喜欢
    • 2013-09-13
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多