0

I have a text file that contains connected paragraphs. I need to separate each paragraph with a blank line. Each paragraphs should begin with an >FP0 pattern, however because the paragraphs are connected to each other, this pattern is not found at the beginning of the line in the current file. I have tried a sed command but it separated them according the line that contains >FP0 pattern but it did not make it at the beginning of the new paragraphs.

Example of the paragraphs

>FP004340TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT>FP00598AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA>FP005521GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG

The sed code used was

sed '/>/s/^/\n/'

and the output was

>FP004340TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

TTT>FP00598AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

A>FP005521GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG

(I need no characters before >FP0 at the beginning of the new paragraphs.)

1
  • I had to guess a bit as to what the proper formatting should look like here; please review.
    – tripleee
    Apr 21 at 10:51

3 Answers 3

3

You can use perl instead:

$ perl -pe 's/>/\n\n>/g' file


>FP004340TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

>FP00598AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

>FP005521GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG

But that adds an extra blank line if the first character of the file is a >. So you can limit it to only replace > if they are preceded by another character:

$ perl -pe 's/(.)>/$1\n\n>/g' file
>FP004340TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

>FP00598AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

>FP005521GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG

Or, with GNU sed:

$ sed -E 's/(.)>/\1\n\n>/g' file
>FP004340TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

>FP00598AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

>FP005521GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG

And with any sed:

sed 's/\(.\)>/\1\
\
>/g' file
>FP004340TTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTTT

>FP00598AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

>FP005521GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG
1
  • +1. With perl re, you can also do it without capture, using a positive lookbehind - e.g. perl -pe 's/(?<=.)>/\n\n>/g', or perl -pe 's/.\K>/\n\n>/g'. See man perlre and search for Lookaround Assertions
    – cas
    Apr 22 at 22:51
1

Your sed script would look for any line with an > in it, but add a newline at the beginning of that line (that's what ^ means in regex).

Probably try this:

sed 's/>/\n&/g' file

though whether \n produces a literal newline or not will depend on your sed version. The desired behavior would be common on many Linux platforms but they are not all the same. (Perhaps clarify which distro and/or sed version, or try a more portable solution like Awk or Perl.)

awk -F '>' 'BEGIN { OFS="\n>" } { $1=$1 } 1' file

The { $1 = $1 } hack forces Awk to split the line; it otherwise optimizes its processing by simply copying input to output if nothing changed on the line, but this causes it to think something actually changed.

If you need more than one newline, obviously put more than one; change \n to \n\n to get an empty line before each new line.

8
  • Apart from embedded systems, any full-fledged Lilnux distribution should have GNU sed AFAIK. Are you aware of any Linux flavors that do not?
    – terdon
    Apr 21 at 10:54
  • 1
    Some let the admin pick a different sed version but yeah, I was mainly thinking of e.g. Busybox et al.
    – tripleee
    Apr 21 at 10:55
  • There is a correct and portable way to insert a newline in the replacement string and that's escaping an actual line break with a backslash: "A line can be split by substituting a <newline> into it. The application shall escape the <newline> in the replacement by preceding it by a <backslash>."
    – Philippos
    Apr 21 at 10:55
  • by the way, your sed solution will not add a blank line between each "paragraph", it just separates them into lines. It only adds a blank line to the beginning, and only if the > was the first character. Same for the awk solution.
    – terdon
    Apr 21 at 10:56
  • The last paragraph specifically addresses that. The OP's formatting was unclear and I felt it was easier to explain with a single newline with a footnote about adding more, rather than vice versa.
    – tripleee
    Apr 21 at 10:57
0

GNU sed

$ sed 's/>/\n\n&/2g' input_file

POSIXly sed

sed -e '
  y/>/\n/
  s/\n/>/
  s//&&>/g
' input_file

$ perl -pe 's/(?<!^)(?=>)/\n\n/g' input_file
awk -v RS=">" -v ORS= '
NR>1&&sub(/^/,(!k++ ? ORS : "\n\n") RS)
' input_file

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.