LINUX- What is wrong with my code in sed? - sed

I want to replace
ExecStart=/sbin/runuser -l <USER> -c "/usr/bin/vncserver %i"
PIDFile=/home/<USER>/.vnc/%H %i.pid
with
ExecStart=/sbin/runuser -l root -c "/usr/bin/vncserver %i"
PIDFile=/root/.vnc/%H %i.pid
I have tried:
sed -i 's$ExecStart=/sbin/runuser -l <USER> -c "/usr/bin/vncserver %i" \n PIDFile=/home/<USER>/.vnc/%H %i.pid$ExecStart=/sbin/runuser -l root -c "/usr/bin/vncserver %i" \n PIDFile=/root/.vnc/%H %i.pid$g' file
I used $ instead of / for special characters. But that doesn't work, nothing is getting edited.
Please tell me what I am missing. Thx.
Got the Soution.Thx to the answerer :) :
sed -i 's$ExecStart=/sbin/runuser -l <USER> -c "/usr/bin/vncserver %i"$ExecStart=/sbin/runuser -l root -c "/usr/bin/vncserver %i"$g' uu && sed -i 's$PIDFile=/home/<USER>/.vnc/%H %i.pid$PIDFile=/root/.vnc/%H %i.pid$g' uu

sed primarily works on one line at a time, so you'll need to define two separate substitute operations, one for each line:
sed -e 's/-l <USER> -c/-l root -c/' \
-e 's%home/<USER>%root%' \
file
Note that the character after s is the delimiter for the regular expression. Rather than messing with backslashes, I changed to % in the second to avoid the collision with slashes.
If you're really worried, you can make your matches match more, but what I showed is unlikely to fail you. It is odd that you want /root to replace /home/<USER>. You might do better with a marker like <HOME> which can be set correctly.

Related

Using pssh to replace text in place

Anyone here used pssh to modify files in place, I've tried attempts like so;
while read line;
do
pssh --inline-stdout -H "$line" "hostname;
sudo sed -i \'s/search domain123.local/search domain123.local domain456.local/g\' /etc/resolv.conf;
sleep 1";
done < <(cat listOfIPs.txt)
Although pssh returns Success status, it doesn't amend resolv.conf on the actual host - am I missing something obvious in the pssh or sed command?
Thanks!
I found by altering the quotes, from single to double in the sed part, it seemed to fix it:
while read line;
do
pssh --inline-stdout -H "$line" "hostname;
sudo sed -i \"s/search domain123.local/search domain123.local domain456.local/\" /etc/resolv.conf;";
done < <(cat listOfIPs.txt)
And I also removed the /g but I don't think that really made a diff

Modify /etc/sudoers with sed

I'm trying to write a sed program to append Defaults:user !requiretty after the line Defaults requiretty in /etc/sudoers. I tried the following command:
sudo sed -i '/Defaults requiretty/a Defaults:user !requiretty' /etc/sudoers
This is working properly, but only if there are 4 spaces between 'Defaults' and 'requiretty'. I want to modify it in order to work with any number of spaces, so I tried the following:
sudo sed -i '/Defaults\s+requiretty/a Defaults:user !requiretty' /etc/sudoers
I checked the pattern on regexr and it was okay, but still the command does not insert the required line. Why not?
try this;
sed '/Defaults.\s\s.requiretty/a Defaults:user !requiretty' /etc/sudoers
Working from Mustafa's answer, here's a way to do the same thing with some safety checks added
SUDOER_TMP=$(mktemp)
cat /etc/sudoers > $SUDOER_TMP
sed -i -e 's/PATTERN/OUTPUT/' $SUDOER_TMP
visudo -c -f $SUDOER_TMP && \ # this will fail if the syntax is incorrect
cat $SUDOER_TMP > /etc/sudoers
rm $SUDOER_TMP

sed comand is not replacing value after first match

I am trying to add a line in a file using sed after first match. I looked my threads online, addressing the same issue and tried below versions of the command:
sudo sed -e '/cfg_file/cfg_file='$NEW_FILE -e '/cfg_file/cfg_file=/q' MAIN_CONF_FILE
sudo sed -i '0,/cfg_file/ a\cfg_file='$NEW_FILE $MAIN_CONF_FILE
sudo sed -i '1s/cfg_file/cfg_file='$NEW_FILE $MAIN_CONF_FILE
sudo sed -i '1/cfg_file/s/cfg_file='$NEW_FILE $MAIN_CONF_FILE
Unfortunately, nothing worked for me. Either they show error, in case of point 3, or show similar behavior of adding lines after each match.
SAMPLE FILE
cfg_file=some_line1
cfg_file=some_line2
Now I want to add a line after first match of cg_file, like below.
EXPECTED RESULT
cfg_file=some_line1
cfg_file=my_added_line_after_first_match_only.
cfg_file=some_line2
Help me in adding line after first match and correcting my command.
Since you're on Ubuntu, you are using GNU sed. GNU sed has some weird features and some useful ones; you should ignore the weird ones and use the useful ones.
In context, the useful one is ranges starting at line 0. Weird ones are the way it messes with a, i and c commands.
MAIN_CONF_FILE=/tmp/copy.of.main.config.file
NEWFILE="my_added_line_after_first_match_only."
sed -e '0,/^cfg_file=/ { /^cfg_file/ a\' \
-e "cfg_file=$NEWFILE" \
-e '}' \
"$MAIN_CONF_FILE"
In classic sed, the a command is followed by backslash-newline, and each subsequent line of the script is appended up to and including the first line without a backslash at the end (and the backslash is removed). Each -e argument functions as a line in the script. Distinguish between the shell lines escaped with backslash at the end and the sed script lines with backslash at the end.
Example at work
$ cat /tmp/copy.of.main.config.file | so
cfg_file=some_line1
cfg_file=some_line2
$ cat script.sh
MAIN_CONF_FILE=/tmp/copy.of.main.config.file
NEWFILE="my_added_line_after_first_match_only."
SED=/opt/gnu/bin/sed
${SED} \
-e '0,/^cfg_file=/ { /^cfg_file/ a\' \
-e "cfg_file=$NEWFILE" \
-e '}' \
"$MAIN_CONF_FILE"
$ bash script.sh
cfg_file=some_line1
cfg_file=my_added_line_after_first_match_only.
cfg_file=some_line2
$
This is based on your attempt 2, but avoids some of the weird stuff.
Basic sanity
As I noted, it is not sensible to experiment with sudo and the -i option to sed. You don't use those until you know that the script will do the job correctly. It is dangerous to do anything as root via sudo. It is doubly dangerous when you don't know whether what you're trying to use will work. Don't risk wrecking your system.

Find and replace texts in Linux

Can someone tell me the command in Linux to replace the following?
ExecStart=/sbin/runuser -l <USER> -c "/usr/bin/new %i"
PIDFile=/home/new/.new/%H %i.pid
with
ExecStart=/sbin/runuser -l <USER> -c "/usr/bin/vncserver %i"
PIDFile=/home/NUSER/.new/%H %i.pid
I am a little bit confused with sed as I don't know how to insert line break while replacing.
sed -i -r 's#/bin/new#/bin/vncserver#; s#/home/new#/home/NUSER#' file
This might work for you (GNU sed):
sed -r '$!N;s/^(ExecStart=.*)new(.*\nPIDFile=.*\/)new(.*)/\1vnserver\2NUSER\3/;P;D' file
Keep two lines in the pattern space and when the required lines are encountered, replace the two strings.

sed: can't read /home/me/weather: No such file or directory

I have the following extract from a script that fetches weather information from accuweather:
wget -O ./weather_raw $address
if [[ -s ./weather_raw ]]; then
egrep 'Currently|Forecast<\/title>|_31x31.gif' ./weather_raw > ./weather
sed -i '/AccuWeather\|Currently in/d' ./weather
sed -i -e 's/^[ \t]*//g' -e 's/<title>\|<\/title>\|<description>\|<\/description>//g' ./weather
sed -i -e 's/<img src="/\n/g' ./weather
sed -i '/^$/d' ./weather
sed -i -e 's/_31x31.*$//g' -e 's/^.*\/icons\///g' ./weather
sed -i -e '1s/.$//' -e '3s/.$//' -e '6s/.$//' ./weather
for (( i=2; i<=8; i+=3 ))
do
im=$(sed -n ${i}p ./weather)
sed -i $i"s/^.*$/$(test_image $im)/" ./weather
done
fi
The command that triggers the code above is in a conkyrc file and its ~/.conkyblue/accu_weather/rss/acc_rss. When I run the conkyrc script from the prompt, I get an error
sed: can't read /home/me/weather: No such file or directory
And indeed when I check, the "weather" file is not created. However if run the command ~/.conkyblue/accu_weather/rss/acc_rss directly from the prompt, it works as expected and create and puts content into the /home/me/weather file.
I don't know anything about the sed command although I'm trying to learn it as a result of this bother.
What could be the problem with the code. I don't think its a permission issue since the folder its writing into is my home folder and I of-course own it.
Thanks
It should have been created by egrep.
When you run your script, the weather directory will be created in the pwd of the script process.
Check and see why egrep does not create the file, or in which directory it created it.