我正在运行GNU bash,版本4.3.46(2)-release(x86_64-pc-msys)
可重复的例子
我有一个大的制表符分隔的文本文件,有许多行和列。 这只是数据格式的一个例子
echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t' Test-123 AAC - - TG
问题
我想要的输出文件的例子:
Test-123 AACNNTG
我试过的解决scheme
我试着逃避 – 使用sed
sed -e 's,\<-\>,N,g'
它没有工作,我检查前后的字符数,他们是一样的
tr -cd - < test2_chr01.txt | wc -c
任何帮助将非常感激。
谢谢!
sed -e 's/\t-/\tN/g'
据我所知,短划线除非在方括号内使用,否则不需要转义。
这只是假设只有第一列不应该有tab-dash被替换,并且它对最后一列工作得很好。
另一个awk:
$ a='Test-123\tA\tA\tC\t-\t-\tT\tG\t' $ echo -e $a | awk 'BEGIN{FS=OFS="\t"}{for(i=1;i<=NF;i++)if($i=="-")$i="N"}1' Test-123 AACNNTG
解释:
awk ' BEGIN { FS=OFS="\t" } # delimiters { for(i=1;i<=NF;i++) # for each field if($i=="-") # if a single dash $i="N" # overwrite it }1' # output
编辑 :如果你正在寻找一个sed
解决方案:
$ echo -e $a | sed -e 's/\B-\B/N/g' Test-123 AACNNTG
显然\B
只在GNU sed上工作( 这里 )
另一个编辑 :使用perl和lookahead。 我们用\tN
替换\t-
,前者后面是\ţ
。 这样我们可以避免重叠区域:
$ echo -e $a | perl -ne 's/\t-(?=\t)/\tN/g; print' Test-123 AACNNTG
echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t'|sed 's/\B-\B/N/g'
awk解决方案:
echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t' | awk -v OFS='\t' '{ for(i=2;i<=NF;i++) sub("-","N",$i) }1'
输出:
Test-123 AACNNTG
如果你正在寻找一个sed
解决方案,那么下面应该与gnu sed
工作:
echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t' | sed ':a;s/\t-\t/\tN\t/g;ta;' Test-123 AACNNTG
如果你没有gnu sed
然后使用:
echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t' | sed -e ':a' -e $'s/\\\t-\\\t/\\\tN\\\t/g;ta' Test-123 AACNNTG
如果你有perl
命令行,那么使用这个基于正则表达式的查找:
echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t' | perl -pe 's/(?<=\s)-(?=\s)/N/g' Test-123 AACNNTG
事实上,你想用\tN\n
替换\t-\t
(只减去字段中的字符)。 这里的问题是两个相邻的字段会重叠,所以sed -e 's/\t-\t/\tN\t/g
是不够的。
你必须使用一个真正的脚本说它是文件sedscript:
:top s/\t-\t/\tN\t/ t top
(真正的标签已经注意到\ t在这里,但应该是真正的标签在文件中)
脚本意思是:
:top
:简单的标签 s/\t-\t/\tN\t/
:将“tab – tab”中的一个出现替换为“tab N tab” t top
:如果替换发生循环,否则打印替换的行并迭代到下一个 你这样使用它:
$ echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t' | sed -f sedscript Test-123 AACNNTG
如果您不想使用外部脚本,则可以使用-e一次传递一个命令:
$ echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t' | sed -e ':a' -e $'s/\\\t-\\\t/\\\tN\\\t/g' -e 'ta' Test-123 AACNNTG
尝试这个:
echo -e 'Test-123\tA\tA\tC\t-\t-\tT\tG\t' | sed -e 's/\([[:space:]]\)-\{1,\}/\1N/g'