Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I am trying to use sed to scan through a file and find a pattern, then use part of the matched pattern as a filename and insert the contents of the file at that location. I can get most of it to work, but I can't seem to figure out how to use a back-reference in place of the filename.

The short version is that a need to pre-process a latex file and get rid of all the top level \input commands becauase lilypond-book is Stupid™.

# Setup files for example
$ echo "foo\n\\input{file2}\nfoo" > file1
$ echo "bar\nbar" > file2

# Use sed to find and replace latex \input commands
$ sed $'/^\\\\input{\\(.*\\)}$/ {r file2\n d}' file1
foo
bar
bar
foo

So far so good, but that has a hard coded file name and I need to use the result of the group match above (the part between the { and } delimiters) as the file name. Unfortunately this does not work:

$ sed $'/^\\\\input{\\(.*\\)}$/ {r \\1\n d}' file1
foo
foo

How can I use the matched pattern as the file name in a scenario like this?

share|improve this question
    
The real answer is of course awk. –  Gilles May 10 at 16:48
    
@Gilles I had a hunch that might be the case, but A) my awk skills are nothing to gawk at and B) I already have a whole bunch of sed processing going on so this is easy to work into the script. –  Caleb May 10 at 16:54
add comment

1 Answer 1

up vote 3 down vote accepted

With GNU sed you could do something like:

sed '/^\\input{\(.*\)}$/{s//\1/;s/'\''/&\\&&/g;s/.*/cat<'"'&'/e}"

(that is build a cat<'the-file' command (escaping the quotes in the file name if needed) and use the e flag of the s command (which is GNU specific) to evaluate that command).

share|improve this answer
    
Thanks, and this does get the job done. Yet it also works without the s/'\''/&\\&&/g; bit at all, which makes me wonder what issues you are anticipating that my MWE does not turn up. What does that bit do? –  Caleb May 10 at 15:19
    
Or even sed 's/^[\]input{\([^}]*\)}$/cat \"\1\"/e' file1 maybe? –  steeldriver May 10 at 15:20
1  
@Caleb, that's to take into account input like \input{Caleb's file}. Or \input{'x;rm -rf /;'} –  Stéphane Chazelas May 10 at 15:23
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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