How could I add new string while keeping the tab line? - bash
I tried to add new string using shell script when the code line have "MSG_LOG".
I did add new string at the new line using this shell script,
#!/bin/bash
############Set File Name
fileName=$1
echo ">>>>Set_FileName is done"
echo ">>>>fileName is ${fileName}"
############Get Elements
lineNumArr=(`grep -n "MSG_LOG" $fileName | awk -F ':' '{print $1}'`)
echo ">>>>Getting LineNumArr is done"
for lineNum in "${lineNumArr[#]}"
do
############Replace logger
sed -i "${lineNum} a printf('MSG_Log is show');" $fileName
echo ">>>>Replace_logger is Done"
done
echo ">>>>for loop is closed"
exit
But it doesn't keep tabs on existing lines of code.
For Example, I want to make my .cpp file like this,
#include<iostream>
int main(void){
bool value=true;
....
if(value){
MSG_LOG("VALUE IS TRUE");
printf('MSG_LOG is show');
}
....
But when I actuate this shell script, the result is...
#include<iostream>
int main(void){
bool value=true;
....
if(value){
MSG_LOG("VALUE IS TRUE");
printf('MSG_LOG is show');
}
....
How can I add new code while preserving the tablines?
You should add the same amount of withespace as the previous line when adding a new line.
You want something like this
sed -E 's/^(.*)(MSG_LOG\(.*\);)(.*)$/\1\2\3\n\1printf("MSG_LOG is show");/g'
If I understood correctly.
You don't have to invoke sed once per line as it loops over the entire file.
Also, you need double quotes in printf.
Using sed, you can duplicate the original line containing MSG_LOG and then replace the text, this will keep the tab spacing in place.
$ sed "/MSG_LOG/{p;s/[[:alpha:]].*/printf('MSG_LOG is show');/}" "$fileName"
Related
How to extact value of pattern which is not in comment(another pattern)
Extract "value=" only from non-comment portion See the below sed expression which gets value from commented code as well I tried with grep but that doesn't work also #!/bin/sh #set -x FILE="/tmp/comment.txt" create_file () { echo "/*" > $FILE echo "this is a multi" >> $FILE echo "line with" >> $FILE echo "var=20" >> $FILE echo "and ending the comment */" >> $FILE echo "var=15" >> $FILE # line after comment } create_file cat $FILE # This sed should extract only from var=15 which is not part of # comments, how to do that? # output should be only 15, instead of "20 and 15" sed -n "s/\(var=\)\([0-9]*\)/\2/p" $FILE Actual: /* this is a multi line with var=20 and ending the comment */ var=15 20 15 Expected: /* this is a multi line with var=20 and ending the comment */ var=15 15
This seems to work: sed -n -e:a -e'/\*\//d;/\/\*/{N;ba };s/^var=//p' The easy part is extracting the value from the line; the hard part is removing the comment first. Rough translation: if there's a */ then delete everything; otherwise if there's a /* then read the next line as well and start over; otherwise if the line starts with "var=" then delete that part and print the rest. Note 1: that annoying line break may not be needed in your version of sed. Note 2: I advise you to test this on the command line, before you attempt it from within a script.
This is the cheap and cheerful way to remove comments as you've shown using GNU awk for multi-char RS: $ awk -v RS='[*]/' -v ORS= '{sub("/[*].*","")}1' file var=15 It'll strip the comments no matter where they start/stop on each line: $ cat file here's some text /* here's a comment */ and more text /* bleh */and more /* this is a multi line with ending here */ and more var=20/* and ending the comment */ /* commented */ var=15 $ awk -v RS='[*]/' -v ORS= '{sub("/[*].*","")} 1' file here's some text and more text and more and more var=20 var=15 It just can't identify strings that look like comment starts/stops inside strings or other language-specific constructs. You can pipe that to whatever you like to get the value of var. If that's not all you need then get/use a parser for whatever language your commented code is written in, e.g. see https://stackoverflow.com/a/13062682/1745001 for C/C++.
Replace an unknown string within a line using Bash
I want to be able to modify db001 with a string I pass into the command via CLI. At any given time db001 could be a different value so I can't just look for that value. ./myscript modify_db <new value> myfile.txt ./myscript modify_db mynewdbname002 Before: database_node=db001.mydomain.local After: database_node=mynewdbname002.mydomain.local ./myscript modify_db db003 Before: database_node=mynewdbname002.mydomain.local After: database_node=db003.mydomain.local
You can use this sed command inside your script: sed "s/^\(database_node=\)[^.]*/\1$1/" file Example: s='database_node=db001.mydomain.local' repl() { sed "s/^\(database_node=\)[^.]*/\1$1/" <<< "$s"; } and call it as: repl mynewdbname002 database_node=mynewdbname002.mydomain.local repl db003 database_node=db003.mydomain.local
You could have a script like, just like below taking an input argument having the replacement value, #!/bin/bash perl -lpe "s/database_node=(\w+)/database_node=$1/g" file and just do ./script.sh newdbname Use the -i flag for in-place replacement and -i.bak for in-place replacement with a backup of your original file perl -lpe -i.bak "s/database_node=(\w+)/database_node=$1/g" file (or) with a simple bash function function replaceFile() { perl -lpe -i.bak "s/database_node=(\w+)/database_node=$1/g" file }
I would avoid trying to produce the new state from the previous state and rather just use a template : function modify_db() { echo "database_node=$1.mydomain.local" } I use echo here for illustration but you should obviously do whatever you want to do with the "database_node=$1.mydomain.local". Supposing it should modify the only line starting with database_node from a file db_conf after having printed the old value : function modify_db() { echo "Before: $(grep '^database_node=' db_conf)" sed -i "s/^database_node=.*\.mydomain\.local/database_node=$1.mydomain.local/" db_conf echo "After: $(grep '^database_node=' db_conf)" }
bash: how can I read text in file into string, modify it and save it another file?
I have a file (imaginary): test() { echo ${%%NUMBER%%} } I need: Read it into string variable Replace %%NUMBER%% with number Save it to another file, maintaining the multi-line architecture. How I do it: #!/bin/bash # Full path of this script FILE=`readlink -f "${BASH_SOURCE[0]}"` # This directory path DIR=`dirname "${FILE}"` repl() { STRING=$(cat $DIR/skel.txt) STRING=$(echo $STRING | sed "s/%%NUMBER%%/$1/") echo $STRING } # try it repl 50 > ./out.sh # tried as well: # repl 50 | tee ./out.sh # echo "$(repl 50)" > ./out.sh # STRING=$(echo -e $STRING | sed "s/%%NUMBER%%/$1/") But I always get everything in one line in out.sh file. Need it to stay multiline, as in source. Thanks.
Try this: repl() { sed "s/%%NUMBER%%/$1/" "$DIR/skel.txt" } This is far more efficient, and won't eat your precious newlines.
Add line to Shell Script File
How can I add a line to a shell script, at the very end of a function using bash? Say the line I want to add is: echo "Well Hello There"; and my function is function hello_there { echo "Hi"; echo "Whats popping?"; } The only real constant will be the name of the method hello_there, and the beginning and end brackets... but I need the line to go above the end bracket... and I do not know how many times I will need to be able to do this...
I would not attempt to dynamically change the source of a script. It's too dangerous. There are several alternatives. The one closest to your problem specification would probably be to write the function like this: function hello_there { echo "Hi"; echo "Whats popping?"; ${HELLO_THERE_POSTCMD:-true} } If you want to change the behaviour of this function, for example to have it recursively erase your home directory, you could set the environment variable export HELLO_THERE_POSTCOMD="rm -rf $HOME" before calling your script.
You could look for the closing "}" and replace it with printf '"Well Hello There"; \n}' and insert a new line character after the semi colon, also use printf rather than echo
You can regenerate function code as following : function hello_there { echo "Hi"; echo "Whats popping?"; } cmd='echo \"Well\ Hello\ There \"' type hello_there | tr '\n' ' ' | sed -e "s/.*nction/function/g" | sed -e "s/[(|)]//g" | sed -e "s/\}/\; $cmd\;\}/g"
appending text to specific line in file bash
So I have a file that contains some lines of text separated by ','. I want to create a script that counts how much parts a line has and if the line contains 16 parts i want to add a new one. So far its working great. The only thing that is not working is appending the ',' at the end. See my example below: Original file: a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a b,b,b,b,b,b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a b,b,b,b,b,b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a Expected result: a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,xx b,b,b,b,b,b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a b,b,b,b,b,b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,xx This is my code: while read p; do if [[ $p == "HEA"* ]] then IFS=',' read -ra ADDR <<< "$p" echo ${#ADDR[#]} arrayCount=${#ADDR[#]} if [ "${arrayCount}" -eq 16 ]; then sed -i "/$p/ s/\$/,xx/g" $f fi fi done <$f Result: a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a ,xx b,b,b,b,b,b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a b,b,b,b,b,b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a ,xx What im doing wrong? I'm sure its something small but i cant find it..
It can be done using awk: awk -F, 'NF==16{$0 = $0 FS "xx"} 1' file a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,xx b,b,b,b,b,b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a b,b,b,b,b,b a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,xx -F, sets input field separator as comma NF==16 is the condition that says execute block inside { and } if # of fields is 16 $0 = $0 FS "xx" appends xx at end of line 1 is the default awk action that means print the output
For using sed answer should be in the following: Use ${line_number} s/..../..../ format - to target a specific line, you need to find out the line number first. Use the special char & to denote the matched string The sed statement should look like the following: sed -i "${line_number}s/.*/&xx/" I would prefer to leave it to you to play around with it but if you would prefer i can give you a full working sample.