Click to See Complete Forum and Search --> : leading spaces
Hi everybody --
I have a line in a file with leading spaces that runs:
id="VALUE"
I'm using the cut command on it (so I can replace VALUE with something else) like this:
while f=`line` #read file line by line
do
echo `echo $f | cut -f1 -d\"`'"'$NEWVAL'"'
done < $1 #feed filename to loop
**********
Input:
id="VALUE"
**********
Output:
id="NEWVAL"
Is there a way to retain the leading spaces? Thanks for having a look!
mrBen
09-01-2004, 10:07 AM
You would probably be better off using sed to replace your value, rather than cut. AFAIK it should leave the string intact:
mrben@hobbes:~/www$ cat text.txt
$id="VALUE"
mrben@hobbes:~/www$ cat text.txt | sed 's/VALUE/NEWVAL/'
$id="NEWVAL"
If you don't know VALUE, then you can do this instead:
mrben@hobbes:~/www$ cat text.txt | sed 's/\".*\"/\"NEWVAL\"/'
$id="NEWVAL"
Thanks for the tip, mrBen. It would take a regular expression then to print only the first 4 chars of VALUE?
Is there a way to get sed to replace multiple patterns with new values in one pass? Like replace id1, id2, and id3 with newval1, newval2, and newval3 all at the same time?
(Can you tell I'm not accustomed to using sed? :))
mrBen
09-01-2004, 10:47 AM
Regular expressions with sed are quite simplistic, but they do tend to be a good way to deal with this kind of thing.
Potentially you could use sed to replace multiple things with multiple other things, but it is probably easier (and more readable) to do them each individually.
If you want to replace a single string with another throughout a whole file (eg changing VALUE to NEWVAL throughout the whole text file) then add a g (standing for 'global') after the final / in the expression.
bwkaz
09-01-2004, 07:06 PM
Originally posted by mrBen
If you want to replace a single string with another throughout a whole file (eg changing VALUE to NEWVAL throughout the whole text file) then add a g (standing for 'global') after the final / in the expression. Ah, but adding a 'g' doesn't change anything unless the match pattern appears more than once on a line.
Sed will replace multiple instances of the pattern in any file just fine without g -- you only need g when you want it to replace all instances of the pattern on lines where it appears more than once. By default, it will only replace the first occurrence of the pattern.
;)
As far as replacing id1, id2, id3 with result1, result2, result3, you can use multiple sed scripts to do it:
sed -e 's/id1/result1/g' -e 's/id2/result2/g' -e 's/id3/result3/g' file.txt >newfile.txt
(No need for cat either.)
I found the -e option earlier this morning to eliminate cat, but didn't realize I could have more than one -e [script] per sed command. Cool.
My biggest problem is trying to figure the substring substitution. So far I have
sed -e 's/id="*"/id="[?what goes here?]"/'
Yes, it's a pathetic regex, but I gave up halfway through the morning and tried to do it some other way.
:)
bwkaz
09-02-2004, 06:52 PM
Hmm...
The way the pattern is set up now, sed will match the letter i, followed by the letter d, followed by =, followed by any number of (including 0) double quote characters, followed by one more double quote character.
* does not mean "match any sequence of any character" in regexes. That is what it means in shell globbing (when matching filenames), but not with regexes. In a regex, * means "any number (including 0) of the previous element".
In a regex, the . character means "any single character". So if you wanted to match id="anything", you would need to use this as your pattern regex:
id=".*"
instead.
Now, as for the [?what goes here?] part, you just put whatever you want to replace in there. It has to be a single string, though (unless you want to use &, to replace the entire piece of the string that originally matched, or various backreferences to refer to part of the pattern string). If you want to replace id="<any value>" with id="value1", then you would put the string value1 in where you have your square brackets.
If you wanted the replacement to depend on the part of the pattern that matched, though, you won't be able to use that pattern regex. You'll have to use specific patterns for each replacement you want to do.