Bash 如何防止while循环输出与以前的输出冲突?

Bash 如何防止while循环输出与以前的输出冲突?,bash,Bash,在第一次通过while循环之后,第二次循环的输出附加到第一次循环的最后一行 在这里,我对bash使用了while循环,我怀疑这是一个问题 有两个文件,下面是每个文件的一部分: input1 CGTGGGAA TGTGGGAA CGTGAGAA 以下是相关的代码片段: while IFS= read -r line do OutputA1+=$(grep -o -P "$line" "$namePBM") #Shows Target Site OutputA2+=$(grep -

在第一次通过while循环之后,第二次循环的输出附加到第一次循环的最后一行

在这里,我对bash使用了while循环,我怀疑这是一个问题

有两个文件,下面是每个文件的一部分:

input1
CGTGGGAA
TGTGGGAA
CGTGAGAA
以下是相关的代码片段:

while IFS= read -r line
do
    OutputA1+=$(grep -o -P "$line" "$namePBM") #Shows Target Site
    OutputA2+=$(grep -o -P ".{0,2}$line" "$namePBM" | sed 's/........$//') #5' Flank
    OutputA3+=$(awk -v pat="$line" '$1~pat {print $2}' "$namePBM") #Intensity Values 
done < "$input1"

OutputA4=$(paste <(echo "$OutputA1") <(echo "$OutputA2") <(echo "$OutputA3"))

echo "$OutputA4"

预期的输出应该是
tgggaa
及其下一行的相关数据表单。

好的,现在简单的答案是,您需要在循环的每个迭代结束时发出一个换行符

默认情况下,我认为$()命令capture会丢弃最后一行换行符,这就是导致行重叠的原因

添加
和&echo'
可能就足够了:

while IFS= read -r line
do
  OutputA1+=$(grep -o -P "$line" "$namePBM" && echo '') #Shows Target Site
  OutputA2+=$(grep -o -P ".{0,2}$line" "$namePBM" | sed 's/........$//' && echo '') #5' Flank
  OutputA3+=$(awk -v pat="$line" '$1~pat {print $2}' "$namePBM" && echo '') #Intensity Values 
done < "$input1"

OutputA4=$(paste <(echo "$OutputA1") <(echo "$OutputA2") <(echo "$OutputA3"))

echo "$OutputA4"
即:

  • -n
    不打印不匹配的行
  • 替换为所有转义
  • /
    捕获模式:
  • (\([^]\{0,2\}\)\\[^]*\([^]\{2,2\}\)
    第一个单词最多2个字符,或者任意字符加上我们想要的2个字符
  • \(“$line”\)
    Unescape并捕获我们想要的短语
  • [^]*
    放弃该单词的其余部分
  • []*
    在下一个单词之前放弃任何多余的空格
  • ([^]*)完全捕获第二个单词之前的空格
  • *$
    丢弃,直到行尾
  • /\4\2\3\5
    替换为:测试短语,最多2个字符,或在第二个单词前正好2个字符
  • /p'
    打印它(因为-n)
哦,你可以用
\S
代替
[^]
\S
代替
[]

另一种方法是将我们想要的所有单词组合成一个变量,然后只使用一次sed,但这将取消包含2个或更多模式的任何行的复制:

构建我作为练习留下的字符串,但为了展示它的效果:

lines="CGTGGGAA""\|""TGTGGGAA""\|""CGTGAGAA"
sed -n 's/^\(\([^ ]\{0,2\}\)\|[^ ]*\([^ ]\{2,2\}\)\)\('"$lines"'\)[^ ]*[ ]*\( [^ ]*\).*$/\4 \2\3 \5/p' $namePBM

比平均的第一个Q好,但我们需要看到一些示例输入。只需要5行,然后编辑样本输出以匹配。但是不得不说,这是一个庞大的外部呼叫集。你不能把它当作一个
awk
脚本吗?很快就会让你成为半古鲁!祝你好运。谢谢你看!我已经按要求添加了一些输入。这是可能的,我将看一看教程,但我是作为一名生物化学家接受正式培训的,所以这是我迄今为止在编程方面的最佳尝试!不,我改变主意了,你实际上想要所有3个输出,但是如果他们发现超过1个匹配呢?由于数据的性质,每行多个匹配的可能性很小(为了进一步阅读,你可以查找基于蛋白质的微阵列)。我认为这个问题发生得太频繁了,不可能是这种性质碰撞的结果(Output4产生约300行,我在这里只附加了一小部分)这些文件有多大?每个有多少行?而
和&echo'
没有明确地解决问题;识别$()丢弃最后一个换行符将允许我开始处理解决方案。谢谢你的努力!“这看起来真的像是我们可以通过多一点信息大大加快的事情……”保罗霍奇斯同意。捕获一次输出,然后修剪掉三列并不困难,但目前David正在有趣地编程:-)
$()
丢弃所有尾随的换行符,因此添加更多的换行符不会改变任何事情。您可以使用
OutputA1+=$(grep-o-P“$line”“$namePBM”)&&OutputA1+=$'\n'
(注意,
&&
意味着只有在
grep
成功的情况下才会添加新行。谢谢@Gordon!最好在单独的一行中添加,尽管作为注释很难做到!)!。
while IFS= read -r line
do
  OutputA1+=$(grep -o -P "$line" "$namePBM" && echo '') #Shows Target Site
  OutputA2+=$(grep -o -P ".{0,2}$line" "$namePBM" | sed 's/........$//' && echo '') #5' Flank
  OutputA3+=$(awk -v pat="$line" '$1~pat {print $2}' "$namePBM" && echo '') #Intensity Values 
done < "$input1"

OutputA4=$(paste <(echo "$OutputA1") <(echo "$OutputA2") <(echo "$OutputA3"))

echo "$OutputA4"
while IFS= read -r line
do
  OutputA1+=$(grep -o -P "$line" "$namePBM") #Shows Target Site
  OutputA1+=$'\n'
  OutputA2+=$(grep -o -P ".{0,2}$line" "$namePBM" | sed 's/........$//') #5' Flank
  OutputA2+=$'\n'
  OutputA3+=$(awk -v pat="$line" '$1~pat {print $2}' "$namePBM") #Intensity Values 
done < "$input1"
  OutputA3+=$'\n'

OutputA4=$(paste <(echo "$OutputA1") <(echo "$OutputA2") <(echo "$OutputA3"))

echo "$OutputA4"
while IFS= read -r line
do
  sed -n 's/^\(\([^ ]\{0,2\}\)\|[^ ]*\([^ ]\{2,2\}\)\)\('"$line"'\)[^ ]*[ ]*\( [^ ]*\).*$/\4 \2\3 \5/p' $namePBM
done
lines="CGTGGGAA""\|""TGTGGGAA""\|""CGTGAGAA"
sed -n 's/^\(\([^ ]\{0,2\}\)\|[^ ]*\([^ ]\{2,2\}\)\)\('"$lines"'\)[^ ]*[ ]*\( [^ ]*\).*$/\4 \2\3 \5/p' $namePBM