第一次通过while循环后,第二次通过的输出将追加到第一次通过的最后一行。
在这里,我正在使用bash的while循环,我怀疑这是一个\ n问题。
有两个文件,每个都有一个:
input1
CGTGGGAA
TGTGGGAA
CGTGAGAA
namePBM
AAAAAACAACAGGAGGGCATCATGGAGCTGTCCAGCCTGT 220.632711
AAAAAACAGCCGGATCACAATTTTGCCGAGAGCGACCTGT 221.514925
AAAAAACGTCCGGTACACCCCGTTCGGCGGCCCAGCCTGT 222.473157
AAAAAACTCTAGACCTTTAGCCCATCGTTGGCCAACCTGT 262.183554
以下是相关的代码段:
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"
输出看起来像这样:
CGTGGGAA AT 500.306264
CGTGGGAA GA 216.029774
CGTGGGAA GT 226.937170
CGTGGGAA CA 283.247237
CGTGGGAA CC 383.089073
CGTGGGAA TA 243.455285
CGTGGGAA C 631.194970
CGTGGGAA CT 318.330615
CGTGGGAA AC 211.895150
CGTGGGAA 840.522056
CGTGGGAA AG 194.045824
CGTGGGAA AA 193.686006
CGTGGGAA TC 282.153144
CGTGGGAA GC 207.303981
CGTGGGAA CG 225.282407
CGTGGGAA TG 220.369882
CGTGGGAATGTGGGAA TTTC 298.320734329.953276
TGTGGGAA AG 203.847257
TGTGGGAA GA 242.392699
TGTGGGAA GT 211.894931
TGTGGGAA AA 199.040909
TGTGGGAA TT 228.433316
TGTGGGAA TG 236.023833
TGTGGGAA AT 320.913155
TGTGGGAA CG 252.373388
TGTGGGAA GC 257.858672
TGTGGGAA TA 224.919676
TGTGGGAA GG 176.379573
TGTGGGAA CA 211.450761
TGTGGGAA AC 315.362784
TGTGGGAA 666.500440
TGTGGGAACGTGAGAA CCAG 187.171859233.376637
预期输出应为TGTGGGAA
,其相关数据形式应在下一行。
答案 0 :(得分:2)
现在的简单答案是,您需要在循环的每次迭代结束时发出换行符。
默认情况下,我认为$()命令捕获会丢弃最后的换行符,然后这会导致行重叠。
添加&& 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"
事实上,不,$()会丢弃所有尾随行(例如@Gordon),所以我们只能离开
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"
出于调试目的,使用grep -n
参数在找到匹配项的namePBM中打印行号也可能会有用。
要在单个sed中执行此操作,就是反省地狱:
while IFS= read -r line
do
sed -n 's/^\(\([^ ]\{0,2\}\)\|[^ ]*\([^ ]\{2,2\}\)\)\('"$line"'\)[^ ]*[ ]*\( [^ ]*\).*$/\4 \2\3 \5/p' $namePBM
done
也就是说:
-n
不会打印不匹配的行's
用所有逃脱的事物代替/
捕获模式:(\([^ ]\{0,2\}\)\|[^ ]*\([^ ]\{2,2\}\)\)
第一个单词中最多2个字符,或者任意字符加上我们想要的2个字符\('"$line"'\)
退出并捕获我们想要的短语[^ ]*
丢弃该单词的其余部分[ ]*
丢弃所有多余的空格,直到下一个单词.*$
丢弃直到行尾/\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