grep with sed inplace - sed

i want to replace clk in set_input to clk_new.
On terminal it works fine:
grep set_input abc.tcl | grep -w clk | sed 's/clk/clk_new/g'
But once i use inplace, save changes to file it changes all in file.i.e
grep set_input abc.tcl | grep -w clk | sed -i 's/clk/clk_new/g' abc.tcl
set_input -clock clk_new -delay 0.2
set_input -clock clk_new -delay 0.5
set_output -clock clk_new -delay 0.2

Any time you find yourself chaining greps+seds you have the wrong approach. In this case all you need is GNU sed (which you're already using due to -i) for word boundaries:
sed -E -i 's/(set_input.*)\<clk\>/\1clk_new/g' abc.tcl

-i option specifies that files are to be edited in-place is used for replace statement on file.
You don't need grep statements.
Try this code:
$ sed -i 's/clk/clk_new/g' abc.tcl

Related

sed replace doesn't work with particular regexp

I'm trying to make a replace with sed:
cat myfile | grep router | sed -e 's/Custom devices \(DiY\) \[CC2530 router\]\(http:\/\/ptvo\.info\/cc2530-based-zigbee-coordinator-and-router-112\/\) \(CC2530\.ROUTER\)/CC2530 router/g'
The output of the piped grep is:
<text text-anchor="middle" x="455.5" y="-31.3" font-family="Times,serif" font-size="14.00" fill="#ffffff">Custom devices (DiY) [CC2530 router](http://ptvo.info/cc2530-based-zigbee-coordinator-and-router-112/) (CC2530.ROUTER)</text>
This works well:
cat myfile | grep Xiaomi | sed -e 's/Xiaomi Aqara temperature, humidity and pressure sensor/AqaraTHP/g'
What am I missing here?
The man page says that
-e command
Append the editing commands specified by the command argument to the
list of commands.
You need to use -E or -r option (whichever is supported by your sed):
cat myfile | grep router | sed -E 's/Custom devices \(DiY\) \[CC2530 router\]\(http:\/\/ptvo\.info\/cc2530-based-zigbee-coordinator-and-router-112\/\) \(CC2530\.ROUTER\)/CC2530 router/g'
With -E, \( denotes a plain ( symbol and ( is the indicator of capturing group.

sed does not recognize -r flag on AIX

thanks in advance for the help.
I have the following line that does work on linux.
myfile (extract)
active_instance_count=
aq_tm_processes=1
archive_lag_target=0
audit_file_dest=?/rdbms/audit
audit_sys_operations=FALSE
audit_trail=NONE
background_core_dump=partial
background_dump_dest=/home1/oracle/app/oracle/admin/iopecom/bdump
...
cat myfile |sed -r 's/ {1,}//g'|sed -r 's/\t*//g' |grep -v "^#"|sed -s "/^$/d" |sed =|sed 'N;s/\n/\t/'|sed -r "s/#.*//g" | sed "s/\t/;/g"|sed "s/\t/;/g"|sed -e "s,',\o042,g"
The result will be:
1;O7_DICTIONARY_ACCESSIBILITY=TRUE
2;active_instance_count=
3;aq_tm_processes=1
4;archive_lag_target=0
5;audit_file_dest=?/rdbms/audit
6;audit_sys_operations=FALSE
7;audit_trail=NONE
8;background_core_dump=partial
9;background_dump_dest=/home1/oracle/app/oracle/admin/iopecom/bdump
But, I can't figure out, how to perform the same command on AIX server.
Help is very welcome.
Regards.
Antonio.
Unless you have a compelling reason to use sed, you could use alternate tools:
awk -v OFS=';' '{print NR,$0}' filename
would produce the desired output.
You could also use perl:
perl -ne 'print "$.;$_"' filename
It appears that your sed expression would skip lines beginning with a #. As such, you could say:
perl -ne '$,=";"; !/^#/ && print ++$i,$_' filename
or something like:
grep -v '^#' filename | awk ...
reformatting your pipeline:
cat myfile |
sed -r 's/ {1,}//g' | # strip all spaces (1)
sed -r 's/\t*//g' | # strip all tabs (2)
grep -v "^#" | # delete all lines beginning `#` (3)
sed -s "/^$/d" | # delete all empty lines (4)
sed = | # interleave with line numbers (5)
sed 'N;s/\n/\t/' | # join line number and line with `\t` (6)
sed -r "s/#.*//g" | # strip all `#` comments (7)
sed "s/\t/;/g" | # replace all tabs with `;` (8)
sed "s/\t/;/g" | # do it again (9)
sed -e "s,',\o042,g" # replace all ' with " (10)
Boiling that down and using cat -n to provide the line numbers up front gets:
cat -n myfile |
sed "$(print 's/\t/;/')
$(print 's/[ \t]*//g')
s/#.*//g
/^$/d
s/'/\"/g"
which behaves identically unless I'm misreading the aix docs. The $(...) construction is command substitution, it runs that command and substitutes its output. print would be printf on linux.

how to use result from a pipe in the next sed command?

I want to use sed to do this. I have 2 files:
keys.txt:
host1
host2
test.txt
host1 abc
host2 cdf
host3 abaasdf
I want to use sed to remove any lines in test.txt that contains the keyword in keys.txt. So the result of test.txt should be
host3 abaasdf
Can somebody show me how to do that with sed?
Thanks,
I'd recommend using grep for this (especially fgrep since there are no regexps involved), so
fgrep -v -f keys.txt test.txt
does it fine. With sed quickly this works:
sed -i.ORIGKEYS.txt ^-e 's_^_/_' -e 's_$_/d_' keys.txt
sed -f keys.txt test.txt
(This modifies the original keys.txt in place - with backup - to a sourceable sed script.)
fgrep -v -f is the best solution. Here are a couple of alternatives:
A combination of comm and join
comm -13 <(join keys.txt test.txt) test.txt
or awk
awk 'NR==FNR {key[$1]; next} $1 in key {next} 1' keys.txt test.txt
This might work for you (GNU sed):
sed 's|.*|/^&\\>/d|' keys.txt | sed -f - test.txt

Replace token in text by the filename

I have a bunch of textfiles that contain the token -filename-. I need to replace it by the real path and filename of the file.
Thats what I have so far:
grep -lr -e '-filename-' *.txt | xargs sed -i
's/-filename-/therealname/g'
Is there a way to replace therealname with the name of the file?
Just do a bit more bash-fu
for x in *.txt; do
sed -i "s/-filename-/$x/g" $x;
done
Of course, the newlines are just for clarity. Feel free to cram that into one line.
like
for f in $(grep...) ; do sed -i "s,-filename-,$f,g" $f ; done
you mean?
With xargs it will be something like this.
grep ... | xargs -I% -n 1 sed -i "s,-filename-,%,g" %
for f in YOUR_FILE_LIST_MASK ; do
sed -i "s:-filename-:${f}" ${f}
done
can do it.

Change sed line separator to NUL to act as "xargs -0" prefilter?

I'm running a command line like this:
filename_listing_command | xargs -0 action_command
Where filename_listing_command uses null bytes to separate the files -- this is what xargs -0 wants to consume.
Problem is that I want to filter out some of the files. Something like this:
filename_listing_command | sed -e '/\.py/!d' | xargs ac
but I need to use xargs -0.
How do I change the line separator that sed wants from newline to NUL?
If you've hit this SO looking for an answer and are using GNU sed 4.2.2 or later, it now has a -z option which does what the OP is asking for.
Pipe it through grep:
filename_listing_command | grep -vzZ '\.py$' | filename_listing_command
The -z accepts null terminators on input and the -Z produces null terminators on output and the -v inverts the match (excludes).
Edit:
Try this if you prefer to use sed:
filename_listing_command | sed 's/[^\x0]*\.py\x0//g' | filename_listing_command
If none of your file names contain newline, then it may be easier to read a solution using GNU Parallel:
filename_listing_command | grep -v '\.py$' | parallel ac
Learn more about GNU Parallel http://www.youtube.com/watch?v=OpaiGYxkSuQ
With help of Tom Hale and that answer we have:
sed -nzE "s/^$PREFIX(.*)/\1/p"