大家好,我的数据看起来像这样
samplename 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ...
samplename2 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 ...
我希望它看起来像这样:
>samplename
0 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 ...
>samplename2
0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 1 0 0 0 ...
[注意 - 每10个数字后显示换行符;我实际上在每200个之后就想要它,但我意识到显示这样的一行不会很有帮助]。
我可以在文本编辑器上使用正则表达式,但我想在bash中使用sed命令,因为我必须多次这样做,每行需要200个字符。
我尝试了这个,但收到了一个错误:
sed -e "s/\(>\w+\)\s\([0-9]+\)/\1\n\2" < myfile > myfile2
sed:1:“s /(&gt; \ w +)\ s([0-9] +)/ ...”:替换模式中未转义的换行符
还有一点需要注意 - 我在Mac上这样做;我知道Mac上的sed
与gnu sed
略有不同。如果你能够给我一个适用于Mac的解决方案,那就太好了。
提前致谢。
答案 0 :(得分:1)
根据您在200个号码后添加的换行请求,您最好使用awk
。
echo "hello 1 2 3 4" | awk '{print ">"$1; for(i=2; i<=NF; i++) {printf("%d ",$i); if((i+1)%2 == 0) printf("\n");}}
打印出来
>hello
1 2
3 4
如果您希望在仅以hello
开头的行上 ,则可以修改为
echo "hello 1 2 3 4" | awk '/^hello / {print ">"$1; for(i=2; =NF; i++) {printf("%d ",$i); if((i+1)%2 == 0) printf("\n");}}
(/ /
中的正则表达式“仅在与此表达式匹配的行上执行此操作”。
您可以将语句if( (i + 1) % 2 == 0)
修改为if( (i + 1) % 100 == 0 )
以获得100位数后的换行符...我只是将其显示为2
,因为打印输出更具可读性。
更新以使其更清洁,请执行以下操作。
使用以下内容创建文件调用breakIt :(如果您不想仅选择以“hello”开头的行,请忽略/^hello /
;但请在代码周围留出{}
,这很重要。)
/^hello/ { print ">"$1;
for(i=2; i<=NF; i++)
{
printf("%d ",$i);
if((i+1)%100 == 0) printf("\n");
}
print "";
}
现在您可以发出命令
awk -f breakIt inputFile > outputFile
这表示“使用breakIt
的内容作为处理inputFile
的命令,并将结果放入outputFile
”。
应该为你做好准备。
编辑以防万一你真的想要一个sed
解决方案,这是一个很好的解决方案(好吧我想是这样)。将以下内容复制到名为sedSplit
s/^([A-Za-z]+ )/>\1\
/g
s/([0-9 ]{10})/\1\
/g
s/$/\
/g
这有三个连续的sed
命令;这些都是各自的,但由于它们插入换行符,它们实际上似乎需要六行。
s/^ - substitute, starting from the beginning of the line
([A-Za-z]+ )/ - substitute the first word (letters only) plus space, replacing with
>\1\
/g - the literal '>', then the first match, then a newline, as often as needed (g)
s/([0-9] ]{10})/ - substitute 10 repetitions of [digit followed by space]
\1\
/g - replace with itself, followed by newline, as often as needed
s/$/\
/g - replace the 'end of line' with a carriage return
您可以像这样调用此sed脚本:
sed -E -f sedSplit < inputFile > outputFile
这使用
-E
标志(使用扩展正则表达式 - 不需要转义括号等)
-f
标记('从此文件中获取指令')
它使整个事情变得更加清洁 - 并为您提供Mac上要求的输出(即使有额外的回车分离组;如果您不想要,请忽略最后两行)。
答案 1 :(得分:1)
$ awk '{print ">" $1; for (i=2;i<=NF;i++) printf "%s%s", $i, ((i-1)%10 ? FS : RS)}' file
>samplename
0 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 ...
>samplename2
0 0 0 0 0 1 1 1 1 1
1 1 1 1 1 1 0 0 0 ...
答案 2 :(得分:1)
fold
是你的朋友:
sed 's/\([^ ]*\) /\1\n/' input | fold -w 100
答案 3 :(得分:0)
在双引号中,反斜杠由shell解释。其中任何一个都应该有用。
sed -e 's/\(>\w+\)\s\([0-9]+\)/\1\n\2/' < myfile > myfile2
sed -e "s/\\(>\\w+\\)\\s\\([0-9]+\\)/\\1\\n\\2/" < myfile > myfile2
PS,我添加了终止斜杠。你有一个s / ... / ...而不是s /.../.../
PS,因为我正在看你的正则表达式,sed会抱怨没有结束。试试这个。
sed -e 's/^\(\w\+\)\s\+/>\1\n/' < myfile > myfile2
MAC版本,限制为200个字符(100个单位和100个空格)
sed -Ee 's/^([a-zA-Z0-9]+) />\1\
/' | sed -Ee 's/(([0-9] ){99}[0-9]) /\1\
/g' < myfile > myfile2
第一个sed将字符串与数字分开,第二个sed将行分开。
答案 4 :(得分:0)
普通的bash:
while read -r name values; do
printf ">%s\n%s\n" "$name" "$values"
done <<END
samplename 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ...
samplename2 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 ...
END
>samplename
0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 ...
>samplename2
0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 ...
假设samplename不包含空格