I am looking for advice on how to search a part of a string within a file and replace the complete line OR append that string to that file if not found. I "played" with sed for a while now, but couldn't get it to work as expected.
I need to add:
/swapfile none swap sw 0 0
to /etc/fstab
(on Ubuntu 14.04 – Trusty Tahr).
Conditions:
- If any line starting with
/swapfile
is present in/etc/fstab
, remove that line and replace with the string provided above - If more than one line starting with
/swapfile
is found, remove them all and append the string above to the end of the file - If no
/swapfile
is present in/etc/fstab
, append the string to/etc/fstab
- The command must not show console output and must be a "one-liner" (due to automation purposes with puppet)
I am confident that's possible, but I simply didn't find a related tutorial about using sed in the way I need it.
I used sudo sed -i '$a/swapfile none swap sw 0 0' /etc/fstab
but this only appends the string 🙁
Best Answer
You can do this with sed — it's Turing-complete. But it isn't the best tool for the job. Sed doesn't have a convenient way of remembering that it's already made a replacement.
What you can relatively easily do with sed is to blank all the lines starting
/swapfile
, and add a new one at the end:but beyond that we're quickly getting into territory where I wouldn't leave such sed code for another sysadmin to maintain, especially when a simple, readable combination of shell commands would do a better job:
If you want to preserve the existing position of the
/swapfile
line if it's there and only modify the file if it needs modifying, a combination of shell logic and awk is a better tool. I've used multiple lines here for clarity but you can put all the code on the same line if you like. As a bonus, if the file already contained the intended line (with exact spacing), it won't be modified.