6

I'd like to do the following, but I can't seem to find an elegant way to do it.

I have a text file that looks like this:

..more values
stuff = 23   
volume = -15
autostart = 12
more values..

Now the "volume" value may change, depending on the circumstance. I need a script that can find that line of text with "volume = xxx" then replace it with the line "volume = 0". What is an elegant solution to this? This line in the text is not guaranteed to be the first line, so I need a way to find it first.

Alireza Fallah
  • 4,609
  • 3
  • 31
  • 57
jliu83
  • 1,553
  • 5
  • 18
  • 23

5 Answers5

13
sed 's/^volume =.*/volume = 0/g' file.txt
Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
  • Thanks for the answer, I need to pipe this back into the file correct? – jliu83 Sep 30 '12 at 18:00
  • 1
    @jliu83 Don't pipe it to the file directly. You can pipe it to a new file, then you can replace the original file with the new one using `mv`. – Lev Levitsky Sep 30 '12 at 18:03
  • 2
    Thanks, and why, might I ask, should I not pipe to the same file? I'm guessing some sort of a race condition concerning reading and writing to the same file? – jliu83 Sep 30 '12 at 18:05
  • 1
    @jliu83 Something like that. Also note that `sed` has `-i` option for modifying files "in place", but it actually creates a temporary file, too. For safety, I'd start with the command I show, and if you're happy with the output, you can add the `-i` option. – Lev Levitsky Sep 30 '12 at 18:07
  • Also, can you explain the `.*` usage? I understand here it means anything that starts with volume, but why not just `*`, why is there a period (ie, why `.*` not `*`)? – jliu83 Sep 30 '12 at 18:21
  • `*` is a quantifier. It means "match the previous expression 0 or more times". In this case the previous expression will be `.`, which is any character. In `volume =*`, it'd mean "zero or more `=` signs". Feel the difference :) See a short reference on [`sed regex`](http://www.gnu.org/software/sed/manual/html_node/Regular-Expressions.html). – Lev Levitsky Sep 30 '12 at 18:36
2

With sed you can say:

sed '/^volume/s/.*/volume = 0/' infile
Thor
  • 45,082
  • 11
  • 119
  • 130
  • can you explain this? usually the "s" option is used before delimiter for substitution. – jliu83 Sep 30 '12 at 18:00
  • The first `/regex/` decides which line the following commands are applied to, in this case any line starting with `volume`. – Thor Sep 30 '12 at 18:11
1

Pipe the contents into this command:

sed -e 's/^volume\s*=\s*-\?[0-9]\+$/volume = 0/'
viraptor
  • 33,322
  • 10
  • 107
  • 191
1

sed 's/^volume=\(.*\)$/volume=1/g' inputfile

Dan
  • 10,531
  • 2
  • 36
  • 55
vara
  • 816
  • 3
  • 12
  • 29
0

@jliu83, do some reading on regular expressions. It'll make the pattern matching in the sed commands more understandable.

http://en.wikipedia.org/wiki/Regular_expression

itsbruce
  • 4,825
  • 26
  • 35