经过大量搜索后,我发现了一些使用sed或tr删除换行符的方法
sed ':a;N;$!ba;s/\n//g'
tr -d '\n'
但是,我无法找到从特定行排除操作的方法。我已经知道可以使用"!"在sed中作为从后续操作中排除地址的方法,但我无法弄清楚如何将其合并到上面的sed命令中。这是我试图解决的一个例子。
我有一个格式化的文件:
>sequence_ID_1
atcgatcgggatc
aatgacttcattg
gagaccgaga
>sequence_ID_2
gatccatggacgt
ttaacgcgatgac
atactaggatcag
at
我希望以这种方式格式化文件:
>sequence_ID_1
atcgatcgggatcaatgacttcattggagaccgaga
>sequence_ID_2
gatccatggacgtttaacgcgatgacatactaggatcagat
我一直专注于尝试排除包含">"字符,因为这是唯一存在于具有">"的行上的常量正则表达式。 character(注意:sequence_ID_n对于前面带有">"的每个条目都是唯一的,因此,不能依赖它来进行正则表达式匹配。)
我试过这个:
sed ':a;N;$!ba;/^>/!s/\n//g' file.txt > file2.txt
它运行时不会产生错误,但输出文件与原始文件相同。
也许我不能用sed这样做?也许我错误地接近了这个问题?我是否应该尝试定义一系列要操作的行(即只有以&#34开头的行之间的行;&#;")?
我是基本文本操作的新手,因此非常感谢任何建议!
答案 0 :(得分:3)
此awk
应该有效:
$ awk '/^>/{print (NR==1)?$0:"\n"$0;next}{printf "%s", $0}END{print ""}' file
>sequence_ID_1
atcgatcgggatcaatgacttcattggagaccgaga
>sequence_ID_2
gatccatggacgtttaacgcgatgacatactaggatcagat
答案 1 :(得分:2)
这可能适合你(GNU sed):
sed ':a;N;/^>/M!s/\n//;ta;P;D' file
从不以>
开头的行中删除换行符。
答案 2 :(得分:1)
由于@ 1_CR已经说@jaypal的解决方案是一个很好的方法。但我真的无法抗拒在纯粹的Bash中尝试它。有关详细信息,请参阅注释:
输入数据:
$ cat input.txt
>sequence_ID_1
atcgatcgggatc
aatgacttcattg
gagaccgaga
>sequence_ID_2
gatccatggacgt
ttaacgcgatgac
atactaggatcag
at
>sequence_ID_20
gattaca
剧本:
$ cat script
#!/usr/bin/env bash
# Bash 4 - read the data line by line into an array
readarray -t data < "$1"
# Bash 3 - read the data line by line into an array
#while read line; do
# data+=("$line")
#done < "$1"
# A search pattern
pattern="^>sequence_ID_[0-9]"
# An array to insert the revised data
merged=()
# A counter
counter=0
# Iterate over each item in our data array
for item in "${data[@]}"; do
# If an item matches the pattern
if [[ "$item" =~ $pattern ]]; then
# Add the item straight into our new array
merged+=("$item")
# Raise the counter in order to write the next
# possible non-matching item to a new index
(( counter++ ))
# Continue the loop from the beginning - skip the
# rest of the code inside the loop for now since it
# is not relevant after we have found a match.
continue
fi
# If we have a match in our merged array then
# raise the counter one more time in order to
# get a new index position
[[ "${merged[$counter]}" =~ $pattern ]] && (( counter++ ))
# Add a non matching value to the already existing index
# currently having the highest index value based on the counter
merged[$counter]+="$item"
done
# Test: Echo each item of our merged array
printf "%s\n" "${merged[@]}"
结果:
$ ./script input.txt
>sequence_ID_1
atcgatcgggatcaatgacttcattggagaccgaga
>sequence_ID_2
gatccatggacgtttaacgcgatgacatactaggatcagat
>sequence_ID_20
gattaca
答案 3 :(得分:1)
使用GNU sed:
sed -r ':a;/^[^>]/{$!N;s/\n([^>])/\1/;ta}' inputfile
为了您的输入,它会产生:
>sequence_ID_1
atcgatcgggatcatgacttcattgagaccgaga
>sequence_ID_2
gatccatggacgttaacgcgatgactactaggatcagt
答案 4 :(得分:0)
Jaypal的解决方案是要走的路,这里是一个GNU awk变体
awk -v RS='>sequence[^\\n]+\\n'
'{gsub("\n", "");printf "%s%s%s", $0, NR==1?"":"\n", RT}' file
>sequence_ID_1
atcgatcgggatcaatgacttcattggagaccgaga
>sequence_ID_2
gatccatggacgtttaacgcgatgacatactaggatcagat
答案 5 :(得分:0)
以下是使用awk
awk '{printf (/^>/&&NR>1?RS:"")"%s"(/^>/?RS:""),$0}' file
>sequence_ID_1
atcgatcgggatcaatgacttcattggagaccgaga
>sequence_ID_2
gatccatggacgtttaacgcgatgacatactaggatcagat