我是bash的新手,请原谅我,如果不使用正确的条款。
我需要在一组文件中替换六个字符的某些模式。模式的顺序取决于每个文本字符串的开头。
这是输入的一个例子:
chr1:123-123 5GGGTTAGGGTTAGGGTTAGGGTTAGGGTTA3
chr1:456-456 5TTAGGGTTAGGGTTAGGGTTAGGGTTAGGG3
chr1:789-789 5GGGCTAGGGTTAGGGTTAGGGTTA3
chr1:123-123
等是字符串的名称,它们与我需要通过选项卡处理的字符串分开。我需要使用的字符串由字符5和3分隔,但我可以更改它们。
我希望所有订单中包含T
,A
,G
的所有模式都替换为X
:TTAGGG
,{{1} },TAGGG
,AGGGTT
,GGGTTA
,GGTTAG
。
类似地,包含GTTAGG
的模式(如第3行)的顺序与前一个类似,将替换为不同的字符。
对于构成每个模式的所有6个字符,重复游戏并具有一些特定的差异。
我开始写这样的东西:
CTAGGG
说明
#!/bin/bash
NORMAL=`echo "\033[m"`
RED=`echo "\033[31m"` #red
#read filename for the input file and create a copy and a folder for the output
read -p "Insert name for INPUT file: " INPUT
echo "Creating OUTPUT file " "${RED}"$INPUT"_sub.txt${NORMAL}"
mkdir -p ./"$INPUT"_OUTPUT
cp $INPUT.txt ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
echo
#start the first set of instructions
perfrep
#starting a second set of instructions to substitute pattern with one difference from TTAGGG
onemism
我还需要重复perfrep() {
sed -i -e 's/TTAGGG/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/TAGGGT/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/AGGGTT/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/GGGTTA/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/GGTTAG/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/GTTAGG/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
}
# starting a second set of instructions to substitute pattern with one difference from TTAGGG
onemism(){
sed -i -e 's/[GCA]TAGGG/L/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/G[GCA]TAGG/L/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/GG[GCA]TAG/L/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/GGG[GCA]TA/L/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/AGGG[GCA]T/L/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
sed -i -e 's/TAGGG[GCA]/L/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
}
,T[GCA]AGGG
,TT[TCG]GGG
,TTA[ACT]GG
和TTAG[ACT]G
。
使用此程序,我得到显示的输入
的结果TTAGG[ACT]
在我看来,对于我的工作,第一个和第二个字符串都由X重复制作五次,字符的顺序略有不同。另一方面,第三个可能会被掩盖:
5GGGXXXXTTA3
5XXXXX3
5GGGLXXTTA3
如何告诉脚本如果字符串以5GGGTTA而不是5TTAGGG开头,则必须用
替换5LXXX3
而不是
sed -i -e 's/GGGTTA/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
我需要重复所有案件;例如,如果字符串以GTTAGG开头,我将需要以
开头sed -i -e 's/TTAGGG/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
等等,并添加了我的模式的几种变体。
我需要使用sed -i -e 's/GTTAGG/X/g' ./"$INPUT"_OUTPUT/"$INPUT"_sub.txt
和输入文件的所有行的变体重复替换。
对不起这个问题很抱歉。谢谢大家。
添加Varun提供的信息。
6个字符的模式为TTAGGG
,TTAGGG
,[GCA]TAGGG
,T[GCA]AGGG
,TT[TCG]GGG
,TTA[ACT]GG
,TTAG[ACT]G
。
必须检查每个帧的不同,例如TTAGG[ACT]
我们有6帧TTAGGG
,TTAGGG
,GTTAGG
,GGTTAG
,{{1} },GGGTTA
。
必须将相同的帧应用于包含可变位置的图案。
我将总共检查42种模式,分为7组:一组包含AGGGTT
和衍生框架,6包含具有可变位置的模式及其衍生物。
TAGGGT
和衍生物是最重要的,需要先检查。
答案 0 :(得分:1)
#! /usr/bin/awk -f
# generate a "frame" by moving the first char to the end
function rotate(base){ return substr(base,2) substr(base,1,1) }
# Unfortunately awk arrays do not store regexps
# so I am generating the list of derivative strings to match
function generate_derivative(frame,arr, i,j,k,head,read,tail) {
arr[i]=frame;
for(j=1; j<=length(frame); j++) {
head=substr(frame,1,j-1);
read=substr(frame,j,1);
tail=substr(frame,j+1);
for( k=1; k<=3; k++) {
# use a global index to simplify
arr[++Z]= head substr(snp[read],k,1) tail
}
}
}
BEGIN{
fs="\t";
# alternatives to a base
snp["A"]="TCG"; snp["T"]="ACG"; snp["G"]="ATC"; snp["C"]="ATG";
# the primary target
frame="TTAGGG";
Z=1; # warning GLOBAL
X[Z] = frame;
# primary derivatives
generate_derivative(frame, X);
xn = Z;
# secondary shifted targets and their derivatives
for(i=1; i<length(frame); i++){
frame = rotate(frame);
L[++Z] = frame;
generate_derivative(frame, L);
}
}
/^chr[0-9:-]*\t5[ACTG]*3$/ {
# because we care about the order of the prinary matches
for (i=1; i<=xn; i++) {gsub(X[i],"X",$2)}
# since we don't care about the order of the secondary matches
for (hit in L) {gsub(L[hit],"L",$2)}
print
}
END{
# print the matches in the order they are generated
#for (i=1; i<=xn; i++) {print X[i]};
#print ""
#for (i=1+xn; i<=Z; i++) {print L[i]};
}
IFF您可以生成一个静态匹配顺序,然后您可以使用它 像上面的Awk脚本可以工作。但是你说主要模式应该优先,并且在某些情况下首先应该更好地应用次要规则。 (没有办法)。
如果你需要一个更灵活的匹配模式,我建议你看看&#34;带有回溯的递归正常解析&#34;或者&#34;解析表达式语法&#34;。 但是你不再是一个bash shell了。