I'm writing a script which change IP address every once in a while but for some reason I just can't get this working
sed "s/$curLine/$nextLine/" </etc/network/interfaces>/etc/network/interfaces.new, even if I change the end /g, I will always get "sed unterminated `s' command"
Here is my variables $curLine and $nextLine:
#Find current ip from /etc/network/interfaces
curLine=$(sed -n "/address/p" /etc/network/interfaces)
#Find location of current ip in ips.txt.
newLine=$(sed -n "/$curLine/=" ips.txt)
#Check and set next ip
nextIP=$(($newLine+1))
nextLine=$(sed -n "$nextIP,/address/p" ./ips.txt)
for some reason $nextLine also gives me two ips I don't know why because at the beginning ot worked just fine.
and in the end this is the line which doesn't work as it should.
"s/$curLine/$nextLine/" </etc/network/interfaces>/etc/network/interfaces.new
error message "sed unterminated `s' command". If I replace $nextline with text like "address xxx.xxx.xxx.xx it works just fine.
I have read so many topics where solution was use double quotes but I don't know why it doesn't work with me. I also have a book where's an example which is basically just same what I'm doing but again it doesn't work when I try use it.
Thanks !
The syntax for arithmetic has no extra sigil:
NUM=1
OTHERNUM=$((NUM + 1))
# ^^^^^^^^^^^^
In other words, say nextIP=$((newLine+1)).
Problem solved. I just changed
nextLine=$(sed -n "$nextIP,/address/p" ./ips.txt)
to search range of lines instead of specific line with a pattern.
nextLine=$(sed -n "$nextIP,/$nextIP" ./ips.txt)
Related
NOTE: I am a noob at bash scripts and the awk command - please excuse any dumb mistakes I make.
I am unable to substitute shell variables into my awk pattern. I am trying to scan through a file, find the first occurence of a specific string in the file, and print each line that succeed it in order until it hits an empty string/line.
I don't know the string I am searching for in advance, and I would like to substitute in that variable.
When I run this with the string directly specified (e.g "< main>:"), it works perfectly. I've already searched on how awk patterns work, and how to substitute in variables. I've tried using the -v flag for awk, directly using the shell variable - nothing works.
funcName="<${2}>:"
awk=`awk -v FN="$funcName" '/FN/,/^$/' "$ofile"`
rfile=search.txt
echo -e "$awk" > "$rfile"
The error is just that nothing prints. I want to print all the lines between my desired string and the next empty line.
Could you please try following, haven't tested it because no clear samples but should work.
funcName="<${2}>:"
awk_result=$(awk -v FN="$funcName" 'index($0,FN){found=1} found; /^$/{found=""}' "$ofile")
rfile=search.txt
echo -e "$awk_result" > "$rfile"
Things fixed in OP's attempt:
NEVER keep same name of a variable as a binary's name or on a keyword's name so changed awk variable name to awk_result.
Use of backticks is depreciated now, so always wrap your variable for having values in var=$(......your commands....) fixed it for awk_result variable.
Now let us talk about awk code fix, I have used index method which checks if value of variable FN is present in a line then make a FLAG(a variable TRUE) and make it false till line is empty as per OP's ask.
I am trying to delete a set of lines from a file by passing variables.
Below is my file :
$ cat checking.txt
Starting1
DELETE /*+NESTED_TABLE_SET_REFS+*/ FROM tables1
Ending1
Starting2
update table
set col1=2
where val2=685
Ending2
Starting3
update table
set col1=1
where val1=44
Ending3
so in above files I need to delete lines from 1st line to 4th line.
I used below command and it was working fine.
sed '1,4d' checking.txt
Now I gave variable a a value, like a=4
echo $a
4
Now I tried the sed command like
sed "1,${a}d" checking.txt
sed: 0602-404 Function 1, 4d cannot be parsed.
Can someone please tell me how to pass variable here?
Thanks in Advance
One way you could attempt this problem is in the following way. Assuming you want to delete lines between start and stop, you could write
awk '(NR<start) || (stop<NR)' start=1 stop=4 file
The way you are proposing it to work also works,
start=1
stop=4
sed "${start},${stop}d" file
The reason why it failed in your case is because the variable a seems to have blanks in front of it. You notice this from the errormessage and the blanks space in front of the 4.
Before to write, of course I read many other similar cases. Example I used #!/bin/bash instead of #!/bin/sh
I have a very simple script that reads lines from a template file and wants to replace some keywords with real data. Example the string <NAME> will be replaced with a real name. In the example I want to replace it with the word Giuseppe. I tried 2 solutions but they don't work.
#!/bin/bash
#read the template and change variable information
while read LINE
do
sed 'LINE/<NAME>/Giuseppe' #error: sed: -e expression #1, char 2: extra characters after command
${LINE/<NAME>/Giuseppe} #error: WORD(*) command not found
done < template_mail.txt
(*) WORD is the first word found in the line
I am sorry if the question is too basic, but I cannot see the error and the error message is not helping.
EDIT1:
The input file should not be changed, i want to use it for every mail. Every time i read it, i will change with a different name according to the receiver.
EDIT2:
Thanks your answers i am closer to the solution. My example was a simplified case, but i want to change also other data. I want to do multiple substitutions to the same string, but BASH allows me only to make one substitution. In all programming languages i used, i was able to substitute from a string, but BASH makes this very difficult for me. The following lines don't work:
CUSTOM_MAIL=$(sed 's/<NAME>/Giuseppe/' template_mail.txt) # from file it's ok
CUSTOM_MAIL=$(sed 's/<VALUE>/30/' CUSTOM_MAIL) # from variable doesn't work
I want to modify CUSTOM_MAIL a few times in order to include a few real informations.
CUSTOM_MAIL=$(sed 's/<VALUE1>/value1/' template_mail.txt)
${CUSTOM_MAIL/'<VALUE2>'/'value2'}
${CUSTOM_MAIL/'<VALUE3>'/'value3'}
${CUSTOM_MAIL/'<VALUE4>'/'value4'}
What's the way?
No need to do the loop manually. sed command itself runs the expression on each line of provided file:
sed 's/<NAME>/Giuseppe/' template_mail.txt > output_file.txt
You might need g modifier if there are more appearances of the <NAME> string on one line: s/<NAME>/Giuseppe/g
I searched this but did not find answer for my problem.
I have a configuration file, which has a line like
server_ip=xxx.xxx.xxx.xxx
This file is in every node in a cluster. The server_ip is just an IP address which sometimes needs to change. I understand that it is easy to change the server_ip to a new ip address if the old ip address is given. But I don't want to keep tracking the old IP address. I just want to force the server_ip address to change to a new value. So the point here is that we don't want to use xxx.xxx.xxx.xxx part to recognize this line. Instead we can only use 'server_ip=' as the locator, and after this line being located, we just set the server_ip to a new value.
Thanks.
GNU sed has an in-place option -i. The command is a simple substitute which replaces each string that matches with the new string. We use double quotes so that we can access the environment variable containing the new address. Because of the double quotes we must escape the $ which denotes the EOL in the match pattern or else the shell would try to see a variable name after it.
I didn't test this, so it's probably wrong, but should get you close. (updated to include OP's fixes.)
newIp=1.2.3.4; sed -i bak "s/server_ip=.*\$/server_ip=$newIp/g" configfile
Use SED!
echo "server_ip=xxx.xxx.xxx.xxx" > file.txt
sed 's/server_ip=.*/server_ip=NEW_IP/g' < file.txt > tmpFile
I've researched other questions on here, but haven't really found one that works for me. I'm trying to select a specific line from a file and replace a string on that line with another string. So I have a file named my_course. I'm trying to modify a line in my_course that starts with "123". on that line I want to replace the string "0," with "1,". Help?
One possibility would be to use sed:
sed '/^123/ s/0/1/' my_course
In the first /../ part you just have to specify the pattern you are looking for ^123 for a line starting with 123.
In the s/from/to/ part you have specify the substitution to be performed.
Note that by default after substitution the file will be written to stdout. You might want to:
redirect the output using ... > my_new_course
perform the substitution "in place" using the -e switch to sed
If you are using the destructive in place variant you might want to use -iEXTENSION in addition to keep a copy with the given EXTENSION of the original version in case something goes wrong.
EDIT:
To match the desired lined with a prefix stored in a variable you have to enclose the sed script with double quotes " as using single qoutes ' will prevent variable expansion:
sed "/^$input/ s/0/1/" my_course
Have you tried this:
sed -e '[line]s/old_string/new_string/' my_course
PS: the [ ] shouldn't be used, is there just to make it clear that you should put the number right before the "s".
Cheers!
In fact, the -e in this case is not necessary, I can write just
sed '<line number>s/<old string>/<new string>/' my_course
This is what worked for me on Fedora 36, GNU bash, version 5.2.15(1)-release (x86_64-redhat-linux-gnu):
sed -i '1129s/additional/extra/' en-US/Design.xml
I know you said you couldn't use line numbers; I don't know how to address that part, but this replaced "additional" with "extra" on line 1129 of that file.