Print text lines in tree structure using sed

Viewed 92

Lets say I have text like this:

Lorem ipsum Lorem ipsum
Lorem ipsum Lorem ipsum
1. Row1 Lorem ipsum Lorem ipsum
Lorem ipsum Lorem ipsum
1.1 Row 2 Lorem ipsum Lorem ipsum
Lorem ipsum Lorem ipsum
1.1.1 Row 3 Lorem ipsum Lorem ipsum

the numbers on the begining of lines can consist only "1" with dot and it can go to multiple levels "1.1.1.1.1" etc. and I want using sed command target those lines with numbers and print them in three structure without those numbers so the result would be:

Row1 Lorem ipsum Lorem ipsum
  Row 2 Lorem ipsum Lorem ipsum
    Row 3 Lorem ipsum Lorem ipsum

I tried this command sed -rn 's/1.|1.1|1.1.1/'$'\t/p' Book2.txt but this doesnt print it in tree structure. I can use only sed command.

Can you help me please?

3 Answers

This might work for you (GNU sed):

sed -nE '/^1\./{:a;s/^(\s*)1\.?/\1  /;ta;s/  //p}' file

Replace lines beginning 1. with 2 spaces for each 1. or a single 1, then reduce the indent by 2 spaces and print the result.

The 2 spaces can be replaced by \t if tabs are preferred.

Could you please try following, written and tested with shown samples. In case you are ok with awk, adding for future users also in case anyone wants to refer awk command for this kind of task.

awk '
match($0,/^([0-9]+\.){1,}[0-9]+? /){
  val=substr($0,RSTART,RLENGTH)
  printf("%"count1++"s%s\n",(++count>1?" ":""),substr($0,RSTART+RLENGTH))
  val=""
}
' Input_file

Output will be as follows.

Row1 Lorem ipsum Lorem ipsum
 Row 2 Lorem ipsum Lorem ipsum
  Row 3 Lorem ipsum Lorem ipsum

I sometimes find it easier to take these things one step at a time with sed, especially if the rules are complicated.

Also - you have a few syntax errors in your command:

sed -rn 's/1.|1.1|1.1.1/'$'\t/p'

The . character is a wildcard in sed, so you should escape it as \. to match the literal. Not sure why there is a '$' in there, as well.

Here is a stepped approach:

sed -n -e '/^1/p' Book2.txt | \
sed -e 's/^1\.\s//' \
    -e 's/^1\.1\s/\t/' \
    -e 's/^1\.1\.1\s/\t\t/'
  • The first sed command removes all the lines from Book2.txt that do not begin with 1 and pipes the result to the next command.
  • the second sed command has 3 parts - each matching the condition of your levels - replacing the matches with appropriate tabs.

Here is the result:

Row1 Lorem ipsum Lorem ipsum
    Row 2 Lorem ipsum Lorem ipsum
        Row 3 Lorem ipsum Lorem ipsum
Related