5

I want to put in sudo gedit /etc/sysctl.conf the one line vm.swappiness=10 which I sometimes change.

By default this line doesnt exist so I use echo "vm.swappiness=10" | sudo tee -a /etc/sysctl.conf.

If I would always be putting the same exact line vm.swappiness=10, then in case I want to replace I could use sudo sed -i 's/vm.swappiness=10/vm.swappiness=1/g' /etc/sysctl.conf But since there could be vm.swappiness=12 or something else, I want--with just a single command--to find if, in /etc/sysctl.conf, there exists line starting vm.swappiness=. Then if it does exist I want to remove the whole line (then by appending && echo "vm.swappiness=1" | sudo tee -a /etc/sysctl.conf to that command, it would also subsequently add the new configuration line that I want to the end.

But again since there could be a lot of different parameters in one line, it wouldn't be good to delete it all, but would be better to change only the number (to the immediate right of vm.swappiness=).

What you think? Would it be better to search for vm.swappiness=x(x(x)) with 1 to 3 numbers (of course, 100 also exists...), replace if it's there (by putting it into a variable and using a command like `sudo sed -i 's/$oldline/$newline/g'), and if not then just append vm.swappiness=10?

Eliah Kagan
  • 117,780
Kangarooo
  • 5,075
  • By the way, this is tangential to the fundamental topic of your question, but if you're manually editing a file (like /etc/sysctl.conf) with gedit (or, more generally, running any other graphical program as root unless you know it doesn't touch any user-specific configuration files and are prepared to manually fix permissions on your .Xauthority file if necessary), you should use gksu (or gksudo) instead of sudo. So you'd run gksu gedit /etc/sysctl.conf instead of sudo gedit /etc/sysctl.conf. See https://help.ubuntu.com/community/RootSudo#Graphical_sudo. – Eliah Kagan Nov 22 '11 at 18:41

3 Answers3

7

You can do such replacements with awk.

awk '/^vm.swappiness/ {print "replacement"; found=1} !/^vm.swappiness/ {print $0} END {if (!found) {print "appended" }}' filename

The filename parameter at the end is the name of the text file that contains the lines.

The above command replaces any line that begins with wm.swappiness with replacement (modify to your need). Otherwise prints out the original lines.

If a replacement was made, it is remembered in the found variable. Thus if no replacement was made, the END block appends one line with the appended string (this should also be modified).

(Please note that I am not taking into account the permissions, this is solving only the replacement or append problem).

lgarzo
  • 19,832
  • It allways gives me appended. i also tryd without ^ 4 variants (one/both with/out ^) and still gives appended

    man awk | grep abc [abc...] character list, matches any of the characters abc.... [^abc...] negated character list, matches any character except abc.... %x, %X An unsigned hexadecimal number (an integer). The %X format uses ABCDEF instead of abcdef. /abc/ { ... ; f(1, 2) ; ... }

    – Kangarooo Nov 08 '11 at 16:42
  • 1
    Could you compare your test with mine, it seems to be working for me? http://pastie.org/2831658 – lgarzo Nov 08 '11 at 16:46
  • I found it was W instead of V. this far its woking. Thx. now how could i then put in thouse commands? with/out filename variablable couse maybe sometime append in another file and how to in same file all commands – Kangarooo Nov 08 '11 at 16:54
  • 1
    Oh, sorry for that! I have not really concentrated on the exact text to be replaced, only the method. I'll edit the post to correct that. – lgarzo Nov 08 '11 at 16:57
  • 1
    Two methods come to my mind: 1.) set awk variables with -v var=value, so you can use them inside the awk script. 2.) Or see this question: http://askubuntu.com/questions/76808/how-to-use-variables-in-sed (it demonstrates how to insert variables into quoted strings). – lgarzo Nov 08 '11 at 17:05
  • I cant understand from there and cant find how then to change that line so my lines would go in there interpreted correctly. – Kangarooo Nov 10 '11 at 14:39
  • 1
    To supply "replacement" value for the awk script you can use: awk -v replacement="your_value" '/^vm.swappiness/ {print replacement; found=1} ...'. Please note the omission of the quotes around the replacement variable after the print statement and the -v assignment for this variable. You can use the same method for providing the "appended" value. – lgarzo Nov 10 '11 at 15:17
4

You can use

sed 's/vm.swappiness=[0-9]*/vm.swappiness=1/g' /etc/sysctl.conf

If you don't mind how many digits your number has.

If you want a maximum of 3 digits, you need extended (modern) regular expressions rather than basic regular expressions (BRE's). You then need to provide the -E parameter

sed -E 's/vm.swappiness=[0-9]{1,3}/vm.swappiness=1/g' /etc/sysctl.conf
  • 2
    Ouh yes your line is good ok for changing existing but what if it doesnt exist jet? how to use this solution with below solution? To make test if exists then change if not then do what your line does. – Kangarooo Nov 27 '11 at 19:37
  • perfect, short and all what is needed. Nothing else can be added. finds exact line with any number containing in settings – Kangarooo May 04 '14 at 20:56
1

I'm doing:

( sysctl vm.swappiness=10 ) > /dev/null

if [[ `grep "vm.swappiness=" /etc/sysctl.conf | wc -l` -eq 0 ]]; then
    echo "vm.swappiness=60" >> /etc/sysctl.conf
fi

sed -i -r 's~^vm.swappiness[[:blank:]]*=[[:blank:]]*[0-9]*$~vm.swappiness=10~' /etc/sysctl.conf
Alix Axel
  • 1,033