有选择地重新格式化带有空格和 \n 的文件
Selectively reformatting a file with spaces and \n
我有多个格式如下的文件。这个有 3 个序列(序列数在所有文件中都不同,但总是以“.”结尾)每个有 40 个位置,如第一行中的数字所示。从行的开头(第一行除外)是序列的名称:
3 40
00076284. ATGTCTGTGG TTCTTTAACC
00892634. TTGTCTGAGG TTCGTAAACC
00055673. TTGTCTGAGG TCCGTGAACC
GCCGGGAACA TCCGCAAAAA
ACCGTGAAAC GGGGTGAACT
TCCCCCGAAC TCCCTGAACG
我需要将它转换成这种格式,其中序列是连续的,没有空格,也没有 \n,并且在它们 names.The 之后的新行上,应该保留的唯一空格是在两个数字之间第一行。
3 40
00076284.
ATGTCTGTGGTTCTTTAACCGCCGGGAACATCCGCAAAAA
00892634.
TTGTCTGAGGTTCGTAAACCACCGTGAAACGGGGTGAACT
00055673.
TTGTCTGAGGTCCGTGAACCTCCCCCGAACTCCCTGAACG
尝试过 sed 删除空格和 \n,但不知道如何在第一行之后应用它以及如何避免形成一个巨大的行。
谢谢
我认为这应该可行,但我的输出更长,因为如果我实际连接所有最后的 "orphan" 序列,我会得到更长的一行。
cat input.txt | awk '/^[0-9]+ [0-9]+$/{printf("%s\n",[=10=]); next} /[0-9]+[.]/{ printf("\n%s\n",);for(i=2; i<=NF;i++){printf("%s",$i)}; next} /^ */{ for(i=1; i<=NF;i++){printf("%s",$i)}; next;}'
3 40
请尝试告诉我。
这里有一个 shell 脚本,可以满足您的需要:
head -1 input
awk '
NR == 1 { sequences = ; positions = ; next }
{
if ( ~ /^[0-9]/ ) {
sid = ; = "" ; sequence_name[ NR - 1 ] = sid
sequence[ NR - 1 ] = [=10=]
} else {
sequence[ ( NR - 1 ) % ( sequences + 1 ) ] = sequence[ (NR-1) % ( sequences + 1 ) ] " " [=10=]
}
}
END {
for ( x = 1 ; x <= length( sequence_name ) ; x++ )
{
print sequence_name[x]
print sequence[x]
}
}' input | tr -d ' '
我将 head -1
添加到 shell 的顶部只是为了从您的文件中取出第一行。由于到 tr -d ' '
的管道,我无法输出 awk 脚本中的第一行。
记住空行的位置并将空行前后的行合并:
awk '
NR==1{print;next}
NR!=1 && !empty{arr[NR]= "\n" }
/^$/{empty=NR-1;next}
NR!=1 && empty{printf "%s%s%s\n", arr[NR-empty], , }
' file
我的第二个没有 awk
的解决方案:使用空行作为分隔符将文件与其自身合并
cat >file <<EOF
3 40
00076284. ATGTCTGTGG TTCTTTAACC
00892634. TTGTCTGAGG TTCGTAAACC
00055673. TTGTCTGAGG TCCGTGAACC
GCCGGGAACA TCCGCAAAAA
ACCGTGAAAC GGGGTGAACT
TCCCCCGAAC TCCCTGAACG
EOF
head -n1 file
paste <(sed -n '1!{ /^$/q;p; }' file) <(sed -n '1!{ /^$/,//{/^$/!p}; }' file) |
sed 's/[[:space:]]//g; s/\./.\n/'
将输出:
3 40
00076284.
ATGTCTGTGGTTCTTTAACCGCCGGGAACATCCGCAAAAA
00892634.
TTGTCTGAGGTTCGTAAACCACCGTGAAACGGGGTGAACT
00055673.
TTGTCTGAGGTCCGTGAACCTCCCCCGAACTCCCTGAACG
:
head -n1 file
输出第一行
sed -n '1!{ /^$/q;p; }' file
1!
- 不输出第一行
/^$/q
- 空行时退出
p
打印其他所有内容
sed -n '1!{ /^$/,//{/^$/!p}; }' file
1!
- 忽略第一行
/^$/,//
- 从空行到结尾
/^$/!p
- 如果不是空 tline 则输出
paste <(..) <(...)
- 将两个 seds 合并到一个选项卡
sed 's/[[:space:]]//g; s/\./.\n/
s/[[:space:]]//g;
删除所有空格
s/\./.\n/
用逗号和换行符替换逗号。
我有多个格式如下的文件。这个有 3 个序列(序列数在所有文件中都不同,但总是以“.”结尾)每个有 40 个位置,如第一行中的数字所示。从行的开头(第一行除外)是序列的名称:
3 40
00076284. ATGTCTGTGG TTCTTTAACC
00892634. TTGTCTGAGG TTCGTAAACC
00055673. TTGTCTGAGG TCCGTGAACC
GCCGGGAACA TCCGCAAAAA
ACCGTGAAAC GGGGTGAACT
TCCCCCGAAC TCCCTGAACG
我需要将它转换成这种格式,其中序列是连续的,没有空格,也没有 \n,并且在它们 names.The 之后的新行上,应该保留的唯一空格是在两个数字之间第一行。
3 40
00076284.
ATGTCTGTGGTTCTTTAACCGCCGGGAACATCCGCAAAAA
00892634.
TTGTCTGAGGTTCGTAAACCACCGTGAAACGGGGTGAACT
00055673.
TTGTCTGAGGTCCGTGAACCTCCCCCGAACTCCCTGAACG
尝试过 sed 删除空格和 \n,但不知道如何在第一行之后应用它以及如何避免形成一个巨大的行。
谢谢
我认为这应该可行,但我的输出更长,因为如果我实际连接所有最后的 "orphan" 序列,我会得到更长的一行。
cat input.txt | awk '/^[0-9]+ [0-9]+$/{printf("%s\n",[=10=]); next} /[0-9]+[.]/{ printf("\n%s\n",);for(i=2; i<=NF;i++){printf("%s",$i)}; next} /^ */{ for(i=1; i<=NF;i++){printf("%s",$i)}; next;}'
3 40
请尝试告诉我。
这里有一个 shell 脚本,可以满足您的需要:
head -1 input
awk '
NR == 1 { sequences = ; positions = ; next }
{
if ( ~ /^[0-9]/ ) {
sid = ; = "" ; sequence_name[ NR - 1 ] = sid
sequence[ NR - 1 ] = [=10=]
} else {
sequence[ ( NR - 1 ) % ( sequences + 1 ) ] = sequence[ (NR-1) % ( sequences + 1 ) ] " " [=10=]
}
}
END {
for ( x = 1 ; x <= length( sequence_name ) ; x++ )
{
print sequence_name[x]
print sequence[x]
}
}' input | tr -d ' '
我将 head -1
添加到 shell 的顶部只是为了从您的文件中取出第一行。由于到 tr -d ' '
的管道,我无法输出 awk 脚本中的第一行。
记住空行的位置并将空行前后的行合并:
awk '
NR==1{print;next}
NR!=1 && !empty{arr[NR]= "\n" }
/^$/{empty=NR-1;next}
NR!=1 && empty{printf "%s%s%s\n", arr[NR-empty], , }
' file
我的第二个没有 awk
的解决方案:使用空行作为分隔符将文件与其自身合并
cat >file <<EOF
3 40
00076284. ATGTCTGTGG TTCTTTAACC
00892634. TTGTCTGAGG TTCGTAAACC
00055673. TTGTCTGAGG TCCGTGAACC
GCCGGGAACA TCCGCAAAAA
ACCGTGAAAC GGGGTGAACT
TCCCCCGAAC TCCCTGAACG
EOF
head -n1 file
paste <(sed -n '1!{ /^$/q;p; }' file) <(sed -n '1!{ /^$/,//{/^$/!p}; }' file) |
sed 's/[[:space:]]//g; s/\./.\n/'
将输出:
3 40
00076284.
ATGTCTGTGGTTCTTTAACCGCCGGGAACATCCGCAAAAA
00892634.
TTGTCTGAGGTTCGTAAACCACCGTGAAACGGGGTGAACT
00055673.
TTGTCTGAGGTCCGTGAACCTCCCCCGAACTCCCTGAACG
:
head -n1 file
输出第一行sed -n '1!{ /^$/q;p; }' file
1!
- 不输出第一行/^$/q
- 空行时退出p
打印其他所有内容
sed -n '1!{ /^$/,//{/^$/!p}; }' file
1!
- 忽略第一行/^$/,//
- 从空行到结尾/^$/!p
- 如果不是空 tline 则输出
paste <(..) <(...)
- 将两个 seds 合并到一个选项卡sed 's/[[:space:]]//g; s/\./.\n/
s/[[:space:]]//g;
删除所有空格s/\./.\n/
用逗号和换行符替换逗号。