In bash, how do I search for the following string in a file ~/.netrc and delete that line plus the next two lines if found:
machine api.mydomain.com
Example is:
machine api.mydomain.com
user foo
password bar
It should delete all three lines, but I can't match user and password since those are unknown. The only fixed value is machine api.mydomain.com.
Try:
sed -i '' '/^machine api.mydomain.com$/{N;N;d;}' ~/.netrc
When this finds the line machine api.mydomain.com, it reads in two more lines and then deletes them all. Other lines pass through unchanged.
For GNU sed, the argument to -i is optional. For OSX (BSD) sed, the argument is required but is allowed to be empty as shown above.
Let's google it together - sed or awk: delete n lines following a pattern
So, the answer is sed -e '/machine api.mydomain.com/,+2d' ~/.netrc. Add -i flag if changes need to be done in place.
Related
What I want:
There is a file /scripts/backup/config.cfg which contains variables. In my specific case the important ones are:
BACKUPLOCATION=""
ROOTLOCATION="/backup"
Then there is a script /scripts/backup/performBackup.sh
For a specific reason I want a part of the script do the following operations:
read the value of the variable ROOTLOCATION
add a ("/" and) timestamp (Date&Time)
safe the new created value to BACKUPLOCATION (by replacing its current value)
Example
If this is the previous state of the config.cfg:
BACKUPLOCATION="dummy"
ROOTLOCATION="/backup"
After the script ran it should be:
BACKUPLOCATION="/backup/2020-05-02-23-00"
ROOTLOCATION="/backup/"
What I tried
First of all the config file gets "loaded" using
source /scripts/backup/config.cfg
I then tried to use the sed command but the quotes are messing with me. Here is one try (which didn't work):
sed -i 's/BACKUPLOCATION\=.*/BACKUPLOCATION="'$ROOTLOCATION/$(date +%Y-%m-%d-%H-%M)'"/' /scripts/backup/config.cfg
Try this:
source /scripts/backup/config.cfg
sed -i 's|BACKUPLOCATION=.*|BACKUPLOCATION="'"$ROOTLOCATION/$(date +%Y-%m-%d-%H-%M)"'"|' /scripts/backup/config.cfg
The problem with your sed is that you use / as delimiter, which is present in $ROOTLOCATION after expansion, therefore sed fails. I used |, which is usually is not present in filenames. If you ever create a file with |, that sed will fail too! So, "know your data" :)
\#Add another new line of text to hosts and send the output to
hosts_update.sh
sed '/localhost/a\
# Gateway
10.0.0.1 it20.it.cs.umb.edu it20
# Addresses for the Windows PCs
10.0.0.240 it21.it.cs.umb.edu it21\
10.0.0.241 it22.it.cs.umb.edu it22\
10.0.0.242 it23.it.cs.umb.edu it23\
10.0.0.243 it24.it.cs.umb.edu it24\
10.0.0.244 it25.it.cs.umb.edu it25\
10.0.0.245 it26.it.cs.umb.edu it26\
10.0.0.246 it27.it.cs.umb.edu it27\
10.0.0.247 it28.it.cs.umb.edu it28\
' hosts > hosts_update.sh
First things first, your initial couple of lines look way off for a shell script. It looks like your hosts_update.sh line should be part of the comments (and the comment shouldn't start with a \ anyway):
# Add another new line of text to hosts and send the output
# to hosts_update.sh
Secondly, you need a \ at the end of each line that you're appending with sed, at the moment you only have it on certain select lines. With that in mind, this script is probably what you wanted:
# Add another new line of text to hosts and send the output
# to hosts_update.sh
sed '/localhost/a\
\
# Gateway\
10.0.0.1 it20.it.cs.umb.edu it20\
\
# Addresses for the Windows PCs\
10.0.0.240 it21.it.cs.umb.edu it21\
10.0.0.241 it22.it.cs.umb.edu it22\
10.0.0.242 it23.it.cs.umb.edu it23\
10.0.0.243 it24.it.cs.umb.edu it24\
10.0.0.244 it25.it.cs.umb.edu it25\
10.0.0.245 it26.it.cs.umb.edu it26\
10.0.0.246 it27.it.cs.umb.edu it27\
10.0.0.247 it28.it.cs.umb.edu it28\
' hosts > hosts_update.sh
What's actually happening in your case (without the \ continuation characters):
sed '/localhost/a\
# Gateway
10.0.0.1 it20.it.cs.umb.edu it20
is that:
you append a single blank line after localhost;
then you have a sed comment line;
then you tell sed to execute . on line number ten.
At that point, sed rightly complains it has no idea what to do with the . command :-)
I'd say, based on experience, an earlier (working) iteration of the script had only the it21-28 lines and someone added (badly) the it20 and comment/blank lines. That's based on the fact only those lines are the errant ones. However, that's just (informed) speculation and doesn't affect the answer.
And, finally, you probably don't want to call the resultant file hosts_update.sh, people will almost certainly think it's a shell script rather than the hosts file it actually is.
I am not that good on linux shell script and I need little help.
I want to edit a file via script (finding the line and edit).
The Original line is:
# JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=< hostname >"
I want to uncomment and replaye hostname with 127.0.0.1
JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=127.0.0.1"
You can refer to the set command, change the filename with the name you are working at,
sed -i 's## JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=< hostname >"#JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=127.0.0.1"#' filename
Fine answers, but they don't do anything by way of TEACHING the gentleman how and why it works.
If you were using the mundane text editor, ed, you would use three commands after invoking the command "ed filename":
s/^# //
s/< hostname>/127.0.0.1/
w
So, you can use a pipe to submit those commands directly to ed, specifying "-" as its first argument so that it doesn't bother you by reporting character counts upon reading in and writing out the file:
( echo 's/^# //'; echo 's//127.0.0.1/'; echo w ) | ed - filename
You don't need to echo 'q' also because ed will automatically quit when it runs out of input or encounters "end of file" (you can simulate this on the keyboard by just hitting the CTRL-D key rather than actually typing q ).
Here's one way to do it:
sed -i -e 's/# \(JVM_OPTS=.*=\).*/\1127.0.0.1"/' path/to/file
That is, replace the line with the text captured within the group \(JVM_OPTS=.*=\), so everything from JVM_OPTS= until another = sign, and append 127.0.0.1" to the end.
If there might be other lines in the file starting with # JVM_OPTS=,
then you could make the pattern matching more strict, for example:
sed -i -e 's/# \(JVM_OPTS="$JVM_OPTS -Djava.rmi.server.hostname=\).*/\1127.0.0.1"/' path/to/file
I would like to do a sed command in Linux to uncomment the "#auth"
Original file
#%PAM-1.0
auth sufficient pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth sufficient pam_wheel.so trust use_uid
I can write this command to do it:
sed 's/#auth.*sufficient.*pam_wheel.so trust use_uid/auth\t sufficient\t pam_wheel.so trust use_uid/' /etc/pam.d/su
But I think it is too long. Is there any better way to do this (more generic)?
I don't want to specific the line number to replace it, because if someone changed the file, the script will not run normally.
For example:
Search keyword "#auth.*sufficient.*pam_wheel.so trust use_uid", if found, replace this the word "#auth" to "auth", and then append the later wording in the line
With GNU sed, look up the -i option that allows in-place modification and then anchor the regular expression. For instance:
sed -i '/^#auth.*pam_wheel/s/^#//' INPUTFILE
will look for lines beginning with "#auth" that include "pam_wheel" later on the line and replace the "#" at the beginning with nothing.
Here is an extract from a script showing the variables for the script
PathToPiconPNG="/var/OscamSrvidPicon/picon/19.2E/"
PathToOscamSrvid="/var/OscamSrvidPicon/picon/19.2E/oscam.srvid"
PathToPiconTPL="/var/OscamSrvidPicon/oscam_picons/"
PathToTmp="/tmp/"
I want to run this script numerous times replacing (for example) this line:
PathToPiconPNG="/var/OscamSrvidPicon/picon/19.2E/"
with this lines
PathToPiconPNG="/var/OscamSrvidPicon/picon/28.2E/"
I have tried using sed (I know this example is wrong but you might get what im trying to achieve)
sed 's/{PathToPiconPNG="/var/OscamSrvidPicon/picon/19.2E/"}/{PathToPiconPNG="/var/OscamSrvidPicon/picon/28.2E/"}/g' filename.txt > newfilenam.txt
If that is not possible, is there any way that I can set the variable externally from another script
sed -E 's/picon\/.+\//picon\/28.2E\//' filename.txt > newfilenam.txt