1

When trying to replace the following text I receive the error:

sed -i "s/ type pulse fallback "sysdefault" hint { show on description "Default ALSA Output (currently PulseAudio Sound Server)" }/ type plug slave.pcm hw/g" .asoundrc 

no matches found: (currently PulseAudio Sound Server)\n }/ type plug\n slave.pcm hw/g

I've already tried to escape the " using \ or exchange them to ' but the error is:

sed: -e expression #1, char 14: unterminated `s' command

Is the issue related to the empty space/new lines? What would be the most simple way to do this using sed, awk or perl? Thank you very much!

3 Answers 3

2

Using in multiline mode:

perl -i -0 -pe ' s/type pulse.*PulseAudio Sound Server\)/ type plug\n slave.pcm hw/s ' file 

 Output

type plug slave.pcm hw 

Note

What are you really trying to achieve ? Maybe there's a better way.

Sign up to request clarification or add additional context in comments.

3 Comments

Very interesting! My input returns an excedent " and } . I can`t remove the } even using \, tried with and without spaces and it does not work... perl -i -0 -pe ' s/type pulse.*PulseAudio Sound Server)\"/ type plug\n slave.pcm hw/s ' [About the note] I'm trying to automate the audio file editing, but since I do not know if there are differences along linux distros I need to change only when I find this exact block code. Thanks for the code!
Thanks. It worked in my case, but could you explain the parameters -i -0 -pe ? Please
-i is to edit the file, -O is paragraph mode
1

Commands in sed are separated by newlines. To match multiline strings, you can read multiple lines in pattern space with N command, then match them with \n regex for matching the newline. If the match is not found, you have to shuffle with hold space to: hold the pattern space, print everything up until the newline, switch pattern with hold space, remove from pattern everything up until first newline, read next line, repeat.

That would be something along:

sed ' : restart N;N;N;N;N; # read six lines, we need that many : loop # match six lines / type pulse\n fallback "sysdefault"\n hint {\n show on\n description "Default ALSA Output (currently PulseAudio Sound Server)"\n }/{ # replace them s// type plug\n slave.pcm hw/ # print and start over n ; b restart } # hold, print leading line, change, remove leading line h ; s/\n.*// ; p ; x ; s/[^\n]*\n// # append next line and loop N b loop ' 

As writing such scripts is hard (for most people ;), some just use GNU sed -z option:

sed -z 's/ type pulse\n fallback "sysdefault"\n hint {\n show on\n description "Default ALSA Output (currently PulseAudio Sound Server)"\n }/ type plug\n slave.pcm hw/g' 

Note I think that using \n in replacement string inside s command is a GNU extension anyway.

2 Comments

Wow, the big example is awesome! What resources do you recommend to study sed and awk? Thank you very much for the detailed explanation and both answers!
sed introduction by Bruce Barnett is still the first one in google to come out and was great. One day it just "clicked" with me what is pattern and hold space - after understanding that, it's just scripting. There is also awk introduction on grymoire.com too.
0

As others comment, sed processes a file line by line and cannot handle multiple lines as a default behavior. A possible workaround is to slurp all lines in the pattern space with N command at the first stage and perform the substitution(s) in the next step. Then how about:

sed ' :l N $!b l s/ *type pulse\n *fallback "sysdefault"\n *hint {\n *show on\n *description "Default ALSA Output (currently PulseAudio Sound Server)"\n *}/ type plug\'$'\n'' slave.pcm hw/g' .asoundrc 

Slurping all the file might be inefficient if the file size is too huge but it will be no problem for most cases nowadays.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.