Suppose I have a string like this
<start><a></a><a></a><a></a></start>
I want to replace values inside <start></start> like this
<start><ab></ab><ab></ab><ab></ab><more></more><vale></value></start>
How do I do this using Sed?
Try this :
sed 's#<start>.*</start>#<start><ab></ab><ab></ab><ab></ab></start>#' file
I get this line with gnu sed :
sed -r 's#(<start>)(.*)(</start>)#echo "\1"$(echo "\2"\|sed "s:a>:ab>:g")"\3"#ge'
see example:
kent$ echo "<start><a></a><a></a><a></a><foo></foo><bar></bar></start>"|sed -r 's#(<start>)(.*)(</start>)#echo "\1"$(echo "\2"\|sed "s:a>:ab>:g")"\3"#ge'
<start><ab></ab><ab></ab><ab></ab><foo></foo><bar></bar></start>
note
this will replace the tags between <start>s which ending with a . which worked for your example. but if you have <aaa></aaa>:
you could do: (I break it into lines for better reading)
sed -r 's#(<start>)(.*)(</start>)
#echo "\1"$(echo "\2"\|sed "s:<a>:<ab>:g;s:</a>:</ab>:g")"\3"
#ge'
e.g.
kent$ echo "<start><a></a><a></a><a></a><aaa></aaa><aba></aba></start>" \
|sed -r 's#(<start>)(.*)(</start>)#echo "\1"$(echo "\2"\|sed "s:<a>:<ab>:g;s:</a>:</ab>:g")"\3"#ge'
<start><ab></ab><ab></ab><ab></ab><aaa></aaa><aba></aba></start>
sed 's/(\<\/?)a\>/\1ab\>/g' yourfile, though that would get <a></a> that was outside <start> as well...
grep -rl 'abc' a.txt | xargs sed -i 's/abc/def/g'
Related
I am trying to use sed to replace the following but not working
replace datetime.now(pytz.utc) with datetime.utcnow() recursively
i have tried the following
grep -rl "datetime.now(pytz.utc)" . | xargs sed -i 's/datetime.now\(pytz.utc\)/datetime.utcnow\(\)/g'
mac command equivalent
LC_ALL=C
grep -e "datetime.now(pytz.utc)" -rl . | xargs sed -i '' 's/datetime.now\(pytz.utc\)/datetime.utcnow\(\)/g'
as you can see i tried to escape all the parentheses but does not work
anyone know how to properly use sed to replace datetime.now(pytz.utc) with datetime.utcnow()?
I tried to explain in the comments, but obviously I wasn't clear. Here are two potential solutions to your problem:
Using your 'grep/xargs' method:
grep -rl "datetime.now(pytz.utc)" . | xargs sed -i 's/datetime.now(pytz.utc)/datetime.utcnow()/g'
Using the 'find/exec' method:
find . -type f -exec sed -i 's/datetime.now(pytz.utc)/datetime.utcnow()/g' {} \;
Both options will replace "datetime.now(pytz.utc)" with "datetime.utcnow()" in the files found. Both answers are platform independent provided you have GNU sed, not BSD sed.
I a file containing the genome ids following NZ_FLAT01000030.1_173 I need to manipulate those ids like this one: NZ_FLAT01000030.1
I tried some but didn't give me the exact thing.
sed 's/_/\t/' output : NZ FLAT01000030.1_173
sed -r 's/_//' output: NZFLAT01000030.1_173
sed -r 's/_//g' output: NZFLAT01000030.1173
How can I do that by using sed command?
Are you trying to remove the undesrscore and the digits following it?
echo 'NZ_FLAT01000030.1_173' | sed -E 's/_[0-9]+//g'
NZ_FLAT01000030.1
$ echo 'NZ_FLAT01000030.1_173' | sed 's/_[^_]*$//'
NZ_FLAT01000030.1
I want to extract /battle/result from following the txt file
$ cat sample
user_id=1234 /battle/start
I run following the sed command
$ cat sample | sed 's|.*\(/.*\)|\1|g'
/start
But, result is deleting /battle, so I can't extract it as I want.
What is wrong with it?
You can remove all characters up to last space:
$ sed 's/.* //' <<< "user_id=1234 /battle/start"
/battle/start
or use cut:
$ cut -d' ' -f2 <<< "user_id=1234 /battle/start"
/battle/start
Sed tries to do a greedy (maximal) match, therefore .* matches your whole line up to but not including the second /.
Try:
< sample sed 's|.* \(/.*\)|\1|g'
or
< sample sed 's|[^/]*\(/.*\)|\1|g'
In your RE the .* is greedy and swallows the /battle part, you could try to invert the logic and delete everything in front of /:
cat sample | sed 's/[^/]*//'
Here [^/]* matches everthing that is not a / and replaces it with nothing.
echo user_id=1234 /battle/start |grep -oP '\s\K.*'
/battle/start
echo user_id=1234 /battle/start |sed -r 's/(^.*\s)(.*)/\2/g'
/battle/start
This is probably a trivial one:
I have a file (my.file) with these lines:
>h1_c1
>h1_c2
>h1_c3
>h2_c1
>h2_c2
>h2_c3
and I want to change it in place to be:
>c1_h1
>c2_h1
>c3_h1
>c1_h2
>c2_h2
>c3_h3
I thought this ought to do it:
sed -i 's/\(\>\)\(h1\)\(\_\)\(.*\)/\1 \4 \3 \2/g' my.file
sed -i 's/\(\>\)\(h2\)\(\_\)\(.*\)/\1 \4 \3 \2/g' my.file
but it doesn't seem to work. How do I do it?
The obvious sed for your example is:
$ sed -i~ -e 's/^>\(h[0-9]\)_\(c[0-9]\)/>\2_\1/' *.foo
I tested this and it works for your example file.
Try this awk
awk -F">|_" '{print ">"$3"_"$2}' my.file > tmp && mv tmp my.file
awk -F">|_" '{print ">"$3"_"$2}' my.file
>c1_h1
>c2_h1
>c3_h1
>c1_h2
>c2_h2
>c3_h2
You can try this sed,
sed 's/>\(h[1-2]\)_\(.*\)/>\2_\1/' yourfile
(OR)
sed -r 's/>(h[1-2])_(.*)/>\2_\1/' yourfile
kent$ sed -r 's/>([^_]*)_(.*)/>\2_\1/' f
>c1_h1
>c2_h1
>c3_h1
>c1_h2
>c2_h2
>c3_h2
you add -i if you want it to happen "in-place"
I have huge XML file with data like this:
<amount quantity="1">12.00</amount>
How can i replace the 12.00 with something else using sed?
Not really enough information in your question but to replace all values of 12.00 with say 24.00 you could do:
$ sed 's/>12\.00</>24.00</g' file.xml
If you are happy with the results you can store them back using the -i option:
$ sed -i 's/>12\.00</>24.00</g' file.xml
A more rubust match would be:
$ sed -r 's_(<amount quantity="[0-9]+">)12.00(</amount>)_\124.00\2_g' file.xml
But you should really parse the XML properly and not force regexp to do something it wasn't designed for.
script.sh:
#!/bin/bash
xml="<amount quantity="1">12.00</amount>"
newxml=`echo $xml | sed -n "s/\(<amount[^>]*>\)\([^<]*\)\(<\/amount>\)/\113.37\3/gp"`
echo "$newxml"
result:
$ ./script.sh
<amount quantity=1>13.37</amount>