0

I used

cat /var/log/apt/history.log > ~/Desktop/allhistory.log && zcat /var/log/apt/history.log*gz >> ~/Desktop/allhistory.log

to create ~/Desktop/allhistory.log.

I can run

sed -r -i.1 '/(^Commandline: apt-get --no-upgrade|^Commandline: apt full-upgrade|^Upgrade: |^End-Date: |^Error: |^Requested-By: |^Commandline: apt-get autoremove|^Commandline: apt autoremove|^Commandline: apt-get --yes|Commandline: apt-get purge|Commandline: apt purge|^Remove: |^Commandline: apt-get dist-upgrade|^Install: |Commandline: aptdaemon|--reinstall|^Commandline: apt-get --yes --no-install-recommends|^Purge:|^Reinstall )/d' allhistory.log

to exclude stuff I don't want. But I also want to include

Commandline: packagekit role='update-packages'

When I try

sed -r -i.1 '/(^Commandline: packagekit role=\'update-packages\'|^Commandline: apt-get --no-upgrade|^Commandline: apt full-upgrade|^Upgrade: |^End-Date: |^Error: |^Requested-By: |^Commandline: apt-get autoremove|^Commandline: apt autoremove|^Commandline: apt-get --yes|Commandline: apt-get purge|Commandline: apt purge|^Remove: |^Commandline: apt-get dist-upgrade|^Install: |Commandline: aptdaemon|--reinstall|^Commandline: apt-get --yes --no-install-recommends|^Purge:|^Reinstall )/d' allhistory.log

I get

bash: syntax error near unexpected token `)'

What do I need to do to include Commandline: packagekit role='update-packages' successfully in the sed command?

2

The queston boils down to "How do I quote/use single quotes inside a single quoted string"?

This answer over on stackoverflow.com explains it. Use

sed -r -i.1 '/(^Commandline: packagekit role='"'"'update-packages'"'"'|^Commandline: apt-get --no-upgrade|
               ^Commandline: apt full-upgrade|
               ....|
               ^Reinstall )/d' allhistory.log

(I added newlines for readability. Drop them in the actual command.)

Basically it is: Replace each inner ' with '"'"'. That is:

  • end the first string with ',
  • append a literal ' inside double quotes ("'"),
  • append the next part of the string again starting with '

If you consider this unreadable then you are right. It is because bash does not have a nice string concatenation operator like other language do. If there was such an operator (+, for example), then it would look like this:

sed … '...role=' + "'" + 'update-packages' + "'" + '|^Commandline…'
#      ssssssss     d     sssssssssssssss     d     ssssssssssssss

Here the ses denote a single quoted string and the ds the double quoted single-quote in-between. Since there is no such + operator in bash you need to stick them together without any spaces in-between and that gives '"'"'.

  • 2
    Personally I find the '\'' quoting style easier to read than '"'"' – steeldriver Jul 9 at 15:32
  • 1
    @steeldriver Yeah, that's another possibility. A matter of taste, I guess. My mnemonic is "SDSDS" (single-double-single-double-single). Yours must be different ;-) – PerlDuck Jul 9 at 16:28
2

Since there are no characters in your regex pattern that the shell will expand when inside double quotes (such as $ or ! for example), you can simply use double quotes around the whole expression:

$ echo "foo 'bar' baz" | sed "s/'bar'/'BAR'/"
foo 'BAR' baz

See for example Single quote within double quotes and the Bash reference manual

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.