how to keep file format when using sed editor? - bash

suppose a file that contains:
a=1234
b=5678
c=word
i am writing a bash script that will change a's value. i use following command:
echo `sed "s/\(a=\).*/\1 new/" file` >file
it gives:
a=new b=5678 c=word
i also tried following (using anchors) still getting same format:
echo `sed "s/\(a=\).*[\n]$/\1 new/" file` >file
echo `sed "s/\(a=\).*'\n'$/\1 new/" file` >file
where i want:
a=new
b=5678
c=word
how to do that?

Use the -i argument to edit the file in place:
sed -i 's/\(a=\).*/\1new/' file

You could a following sed too once.
sed -i '/^a=/s/=.*/=new/g' Input_file

Related

How to replace '/' with '/\' using sed in shell scripting

I am trying to replace
prakash/annam/DevOps ---> prakash/\annam/\Devops
I am using this:
sed "s/'[//]''///\\/g"
Unfortunately, it is not giving the required output can anyone please help with this!!!
you can use a separator other than slash:
$ sed 's#/#\\/#g' <<< "a/b/c"
a\/b\/c
$ sed 's#/#/\\#g' <<< "a/b/c"
a/\b/\c
You can use sed with -i flag to place in place changes to the file
*nix
$ cat test
prakash/annam/DevOps
$ sed -i 's/\//\/\\/g' test
$ cat test
prakash/\annam/\DevOps
MacOS
$ cat test
prakash/annam/DevOps
$ sed -i '' 's/\//\/\\/g' test
$ cat test
prakash/\annam/\DevOps
Use
sed -E 's/\//\/\\/g'
e.g.
$ echo "prakash/annam/DevOps" | sed -E 's/\//\/\\/g'
prakash/\annam/\DevOps

Batch change multiple file names in bash and save output

I'm trying to change multiple file names with a for loop.
This works to send the output to the screen:
for i in *.gz; do echo $i | sed 's/\-//g'; done
However, when I try to overwrite the file name using sed -i, I get this error:
for i in *.gz; do echo $i | sed -i 's/\-//g'; done
sed: no input files
Any suggestions?
there is a command for this
$ rename - '' *.gz
NB. this is the standard one, not the advanced perl version.
Use Perl rename instead:
rename 's/-//g' *.gz
Or use simple parameter expansion:
for i in *.gz; do mv -- "$i" "${i//-}"; done

How to properly use sed in foreach loop

How to properly use sed in for loop? I want to loop through an array and each loop, open a file template.txt, do spring replacement and output result to a file. For example:
values=( "val_1982" "val_1985" "val_1987" )
for i in "${values[#]}"
do
sed -e "s/\${VAL_ID}/$i/" \
-e "s/\${ENTRY}/"local"/" template.txt > outputfile_$i.txt
done
But I get:
bash: template.txt: command not found
bash: template.txt: command not found
bash: template.txt: command not found
The output files are created but all empty.
I replaced with this and it worked:
for i in val_1982 val_1985 val_1987
do
sed -e "s/\${VAL_ID}/$i/" \
-e "s/\${ENTRY}/"local"/" template.txt > outputfile_$i.txt
done

How to use backtick command result with sed?

I want to replace the version in my code using git rev-parse HEAD with template string %VERSION% in a source file.
For simplicity I will use date as version command in this question.
Given test.txt
$ echo "This is test-%VERSION%." > test.txt
$ cat test.txt
This is test-%VERSION%.
Expect
This is test-Sat Dec 2 16:48:59 +07 2017.
These are failed try
$ echo "This is test-%VERSION%." > test.txt
$ sed -i 's/%VERSION/`date`/' test.txt && cat test.txt
This is test-`date`%.
$ echo "This is test-%VERSION%." > test.txt
$ DD=`date` sed -i 's/%VERSION/$DD/' test.txt && cat test.txt
This is test-$DD%.
$ echo "This is test-%VERSION%." > test.txt
$ DD=`date` sed -i "s/%VERSION/$DD/" test.txt && cat test.txt
This is test-%.
Do I really need to use xargs ?
You can embed $(...) within double-quotes, but not in single-quotes:
sed -i "s/%VERSION%/$(date)/" test.txt && cat test.txt
(Same as `...` but you shouldn't use that obsolete syntax, $(...) is better.)
Btw, for testing purposes, it's better to use sed without -i,
so the original file is not modified:
sed "s/%VERSION%/$(date)/" test.txt
As a side note, and this is a completely different discussion,
but worth mentioning here.
This may look like it should work but it doesn't, and you may wonder why:
DD=$(date) sed -i "s/%VERSION%/$DD/" test.txt && cat test.txt
Why it doesn't work?
Because the $DD embedded in the "..." is evaluated at the time the command is executed.
At that time the value of DD is not set to the output of $(date).
In the "..." it will have whatever value it had before executing the command.
For the sed process, the value DD with the output of $(date) is visible,
but sed doesn't use that, because why would it.
The "..." passed to sed is evaluated by the shell, not by sed.
Use double-quotes to do the substitution and avoid using the outdated `` construct but rather use the $(..) syntax for Command substitution
sed -i "s/%VERSION%/$(date)/" file
Also another way if you just want to use the single quotes, would be to wrap the substitution part in double-quotes and then single-quote on top of it, something like sed 's/%VERSION%/'"$(date)"'/' file which is less efficient than simply double-quoting the entire substitution string.

Inserting a line in the beginning of a file using sed in HP-UX

I am trying to insert a line in the beginning of a file using sed.
I tried below commands :
sed -i '1s/^/LINE TO INSERT\n/' test.txt
sed: illegal option -- i --> Error thrown
sed '1i/^/LINE TO INSERT\n/' test.txt
sed: Function 1i/^/LINE TO INSERT\n/ cannot be parsed. --> Error thrown
Both the ways came out to be failed.
Any possible solution to it ? I am using ksh script on HP-UX.
Thanks.
How about good old ed?
printf '%s\n' 1i 'LINE TO INSERT' . w | ed -s file
printf is used to send each command to ed on a separate line.
Alternatively, if you're terrified of ed like me, you can just use a temporary file, as suggested in the comments:
echo 'LINE TO INSERT' > tmp && cat tmp test > new && mv new test && rm tmp
I think you have a typo: you're missing the closing apostrophe from your 1st command. Otherwise it's fine. I.e.:
You have this: sed -i '1s/^/... test.txt
But you need this: sed -i '1s/^/...' test.txt
Putting all together: sed -i '1s/^/LINE TO INSERT\n/' test.txt
Update: if -i is not supported, then you can use a temporary file:
sed '1s/^/LINE TO INSERT\n/' test.txt > /tmp/test.txt.tmp
mv /tmp/test.txt.tmp test.txt

Resources