1

I'm attempting to replace a "fenced" block of text with the output from the tree command in linux (specifically in a make file). Here's my input file:

some text...
[fencetitle]
----
.
├── file1.txt
└── test
    └── file2.txt

1 directory, 2 files
----
some more text...

And I'd like to replace the contents with output from the tree command:

some text...
[fencetitle]
----
.
├── file1.txt
├── newfile.txt
└── test
    └── file2.txt

1 directory, 3 files
----
some more text...

Using the sed command, I can't seem to match using newlines with the line [fencedtitle] and ---- to ----. I am able to replace text between [fencedtitle] and ---- with the following command, however:

sed -n '/\[fencedtitle\]/{:a;N;/----/!ba;N;s/.*\n/REPLACEMENT\n/};p' file

But I can't seem to then replace REPLACEMENT with the output from the tree command. Is sed the right approach here, or is something else more appropriate?

2

You could try something like:

sed -n "/\[fencedtitle\]/{:a;N;/----/!ba;N;s/.*\n/$(tree)\n/};p" file

But this will be problematic if the output of tree contains characters that are special for regex. If you save the output of tree to a file:

tree > my-out

Then you can read it in sed without too many problems:

sed -n '/\[fencetitle\]/{p;n;p;r my-out
:a;n;/^----$/!ba};p' file

(Yes, the r command does require a new line after it, no commands may follow it on the same line.)

The p;n;p; just prints the start of the fence, then we read the file, then we skip everything till the end of the fence.

You can end the line after the r command by splitting out the rest into a separate sed expression:

sed -ne '/\[fencetitle\]/{p;n;p;r my-out' -e ':a;n;/^----$/!ba};p' file
  • Great, that seems to do the trick... any idea how I could include that newline in a makefile? – John Ericksen Feb 19 '18 at 3:57
  • @JohnEricksen if you split it into two -e expressions, you can avoid the newline, see updated answer. – Olorin Feb 19 '18 at 4:03
  • Hmm, I'm getting a bash: !ba}: event not found from the latest command. – John Ericksen Feb 19 '18 at 4:08
  • Did you use double quotes instead of single quotes? – Olorin Feb 19 '18 at 4:11
  • 2
    @JohnEricksen Remember you need to escape $ in a makefile by using $$. You can also add -i to the sed to actually change file. – meuh Feb 19 '18 at 8:00
0

I have done by below method for above example

sed "s/file1.txt/&\n|__newfile/g" example.txt

output

some text...
[fencetitle]
----
.
├── file1.txt
|__newfile
└── test
    └── file2.txt
  • I think you took the example too literally; they’re looking for the output of the tree command to be put between the bracketed text, not a hard-coded replacement after file1.txt of “newfile”. – Jeff Schaller Feb 20 '18 at 3:36

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.