LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   SED special characters issues (https://www.linuxquestions.org/questions/linux-software-2/sed-special-characters-issues-4175448208/)

metallica1973 02-01-2013 12:58 PM

SED special characters issues
 
I am dusting off the sed cobwebs and had a basic question:

I have a file that contains:
Code:

$firewall = "on";
$cache = "on";
$dataset{'mary had a little lamb'} = "on";

and want to only change the contents of what is between the single quotes:
Code:

$dataset{'big bad wolf'} = "on";
I tried several combinations but to no evail:

Code:

sed 's/^\$dataset{'*'} = "on"\;/\$dataset{'big bad wolf'} = "on"\;/' test.txt
sed "s@^$dataset{'*'} = "on";@$dataset{'big bad wolf'} = "on";@" test.txt
sed 's@^*$@&'big bad wolf' test.txt

So essentially saying, whatever sed finds whats in between the single quotes replace it with "big bad wolf"

Someone please enlighten me!

David the H. 02-01-2013 01:09 PM

This is really more of a shell quoting question. You can use soft quotes to escape hard quotes, and vice-versa. In this case surrounding the whole expression in double-quotes lets you use the single quotes literally.

Code:

sed "/dataset/ s/'[^']*'/'new text'/" infile

metallica1973 02-01-2013 01:28 PM

Many thanks for the reply. Can you break down your example for clarification? I am trying to make sense of it.

Code:

sed "/dataset/ s/'[^']*'/'new text'/" infile
The way I interpret this is, look for the first occurrence of dataset and look for the first occurrence of the single quotes '' and replace it with whatever text you want to use. I dont understand why you dont have to include "$" in which all the variable in the file have them.

Code:

$dataset{'mary had a little lamb'} = "on";

David the H. 02-01-2013 02:35 PM

Well, it does rely on the assumption that there is exactly one pair of single quotes on the line. Other than that, remember that regular expressions are unbounded, and will match anywhere in the line. You usually don't need to worry about anchoring them to the ends with "^,$" unless the relative position to them is important.

So the address bracket only needs to contain a pattern that matches the line uniquely. If "dataset" isn't enough, then expand it as appropriate.

Similarly, once the line is matched, we're only interested in the quoted part of it, so we can ignore everything outside of them. Regexes match from left to right, so it starts by scanning the line until it matches the first single quote.

Then the next part of the regex is "[^']*", a continuous string of "not a quote" characters. It's necessary to use a pattern like this since regex is greedy. A simple ".*" would keep matching characters all the way to the end of the line.

We finish off the pattern by matching the closing quote.

Finally, since the left-hand-side match "consumed" the quotemarks as well as the string, the right-hand side substitution has to replace them.

We could get fancier and use capturing parentheses and backreferences, to carry values over from the LHS to the RHS, but that's not really necessary here, is it?


All times are GMT -5. The time now is 02:25 PM.