Sed works differently when run by super user? - sed

I have just encountered the most perplexing (for me) phenomenon.
I have a sed one liner
sed 's/^(\*Default.*:) Letter/$1 A4/g' /usr/share/ppd/hplip/HP/HP-*
This does exactly what I want and replaces "*DefaultPaperDimension: Letter
" with "*DefaultPaperDimension: A4"
But when I run
sudo sed 's/^(\*Default.*:) Letter/$1 A4/g' /usr/share/ppd/hplip/HP/HP-*
Nothing is matched or replaced. "*DefaultPaperDimension: Letter
" remains "*DefaultPaperDimension: Letter"
WHY IS THIS?? 8-/

Thank you for your comments. In searching for the version of sed I discovered that I had created an alias sed='perl -pe' which being a user alias not a global one does not affect sudo.
Thus:
sed 's/^(\*Default.*:) Letter/$1 A4/g' /usr/share/ppd/hplip/HP/HP-*
is actually
perl -pe 's/^(\*Default.*:) Letter/$1 A4/g' /usr/share/ppd/hplip/HP/HP-*
while
sudo sed 's/^(\*Default.*:) Letter/$1 A4/g' /usr/share/ppd/hplip/HP/HP-*
Is actual sed and therefore what it appears to be.
Thanks again.

Related

apply sed command only if no dot before

My sed command does not work as expected.
sed -E ':a;N;$!ba;s/[^\.](\[[0-9]]) \n\n/\1 /g'
I want this :
blabla[3]
foofoo
barbar.[4]
blabla
To become :
blabla[3] foofoo
barbar.[4]
blabla
That is, I just want the new lines to be deleted when there is no dot before "[".
But my sed command does not take into account my [^\.].
Without [^\.], I get :
blabla[3] foofoo
barbar.[4] blabla
You may use this sed (should work with non-gnu sed also):
sed -E -e ':a' -e 'N;$!ba' -e 's/((^|[^.])\[[0-9]+]) *\n\n/\1 /g' file
blabla[3] foofoo
barbar.[4]
blabla
Code Demo
Note that we are matching (^|[^.]) to allow [<digits>] to appear at the line start as well. It is also important to keep this part in capture group so that we don't miss out on this char in replacement.

remove everything between two characters with sed

I'd like to remove any characters between including them also
<img src=\"/wp-content/uploads/9e580e68ed249dec8fc0e668da78d170.jpg\" / hspace=\"5\" vspace=\"0\" align=\"left\">
I was trying
sed -i -e 's/<img src.*align=\\"left\\">//g' file
You do not say what version of sed you are using, or what shell.
With GNU sed and bash, your attempt was almost there. Try:
sed -i 's/<img src[^>]*align=\\"left\\">//g' file
Explanation:
s/<img src[^>]*align=\\"left\\">/ search for <img src_STUFF_align=\"left\">, where _STUFF_ cannot contain any >
// and replace it with nothing
/g and continue
-i and modify the file
I believe this should work with most version of sed (except for the -i).

Same regex in perl and sed work differently

Okay, maybe something wrong with unicode or etc, but the code tells everything:
$ cat leo
сказывать
ссказываю
сказав
BladeMight#Chandere ~ 23:24:58
$ cat leo | perl -pe 's/^с+каз/Рассказ/g'
Рассказывать
ссказываю
Рассказав
BladeMight#Chandere ~ 23:25:00
$ cat leo | sed -r 's/^с+каз/Рассказ/g'
Рассказывать
Рассказываю
Рассказав
I have file leo, contents in cyrillic, so i wanted to replace wrong places with the regex ^с+каз in perl -pe, but it replaces only the ones that have only 1 с(cyrillic one), e.g. + does nothing in this case(and for non-cyrillic it works fine), although in sed -r it works perfectly. Why could that be?
Perl needs to be told that your source code is UTF-8 (-Mutf8) and that it should treat stdin and stdout as UTF-8 (-CS).
$ cat leo | perl -Mutf8 -CS -pe 's/^с+каз/Рассказ/g'
Рассказывать
Рассказываю
Рассказав

SED inplace file change inside make - How?

sed inplace change on a file is not working inside Make object.
I want to replace a line in a file with sed called in a make object. But it does not seem to be working. How can I fix this?
change_generics:
ifeq ($(run_TESTNAME), diagnostics)
ifeq ($(run_TESTCASE), 1)
sed -i -e "s/SIM_MULTI\==[a-z,A-Z]*/SIM_MULTI=TRUE/" ./generics.f
else ifeq ($(TESTCASE), 2)
sed -i -e "s/SIM_MISSED\==[a-z,A-Z]*/SIM_MISSED=TRUE/" ./generics.f
endif
endif
I would like the generics.f file changed with that one line change. But it remains the same as the original. The sed command works outside make.
I can't reproduce this using GNU sed 4.2.2 and GNU make 3.82, or at least, I can't reproduce any scenario where the same sed command works from the command line but not in a Makefile.
Simpler Makefile:
all:
# Contrived just so I can test your 2 sed commands.
sed -i -e "s/SIM_MULTI\==[a-z,A-Z]*/SIM_MULTI=TRUE/" ./generics.f
sed -i -e "s/SIM_MISSED\==[a-z,A-Z]*/SIM_MISSED=TRUE/" ./generics.f
Sample file content in generics.f:
SIM_MULTI=foo
SIM_MISSED=bar
Testing:
$ make all
sed -i -e "s/SIM_MULTI\==[a-z,A-Z]*/SIM_MULTI=TRUE/" ./generics.f
sed -i -e "s/SIM_MISSED\==[a-z,A-Z]*/SIM_MISSED=TRUE/" ./generics.f
Confirmed that both sed commands fail to edit a file with this content.
To fix:
Probably, you need to simply remove the \= from your regular expression. The backslash there has no effect, and causes your regex to simply match two equals signs ==. Thus this works:
all:
sed -i 's/SIM_MULTI=[a-zA-Z]*/SIM_MULTI=TRUE/' ./generics.f
sed -i 's/SIM_MISSED=[a-zA-Z]*/SIM_MISSED=TRUE/' ./generics.f
Testing:
$ make all
sed -i 's/SIM_MULTI=[a-zA-Z]*/SIM_MULTI=TRUE/' ./generics.f
sed -i 's/SIM_MISSED=[a-zA-Z]*/SIM_MISSED=TRUE/' ./generics.f
$ cat generics.f
SIM_MULTI=TRUE
SIM_MISSED=TRUE
Further explanation:
There is no need to specify -e there.
There is no need to enclose the script in double quotes, which is riskier because it allows the contents to be modified by the shell.
The bug appears to be \= and I deleted those characters, as mentioned above.
Note that I removed the comma , as well in [a-z,A-Z]. I think that probably isn't what you meant, and it would cause a class of characters including a-z, A-Z and a comma , to be matched by the regex. (And if it is what you mean, you might consider writing it as [a-zA-Z,] as that would be less confusing.)
If this has not resolved your issue, I would need to know things like:
What is the version of your sed.
What is the contents in generics.f.
POSIX/GNU sed have c for "change":
sed -i '/SIM_MULTI=/c\SIM_MULTI=TRUE'
sed -i '/SIM_MISSED=/c\SIM_MISSED=TRUE'

sed - substitute either of two characters with one command

I would like one sed command to accomplish the following:
$ sed s'/:/ /g' <and> sed s'/=/ /g'
That is, I would like to write
sed s'/<something>/ /g'
and have both = and : replaced by space.
sed s'/[:=]/ /g'
Brackets mean "any one of".
One option is also to use sed -e, like this. Although you don't need it in this case, it's however a good option to know about.
sed -e 's/:/ /' -e 's/..../ /' file
Sanjay's answer solves it. Another option that works with only one sed command is to separate each s substitution with a semicolon
sed 's/:/ /g ; s/=/ /g' file
or in separate lines in a script
sed 's/:/ /g
s/=/ /g' file
Those may be handy in other situations.