sed script to remove everything in brackets over multiple lines - sed

I am trying to use sed script to remove the content of an array in a file. I have tried to delete the content to only leave the brackets (). However I can't get the sed script to work over multiple lines.
I am trying to change the current state of the file:
LIST = ( "content"
"content1"
"content3")
to this:
LIST = ()
However the sed script I am using only changes the file to this:
LIST = ()
"content"
"content1"
"content2"
sed -e 's/LIST=\([^)]*\)/LIST=() /g' filename
I should also mention there are other sets of brackets in the file which I don't want affected.
e.g
LISTNUMBER2("CONTENT")
should not be emptied.

this sed one-liner works for your example:
sed -n '1!H;1h;${x;s/(.*)/()/;p}'
test:
kent$ echo 'LIST = ( "content"
"content1"
"content3")'|sed -n '1!H;1h;${x;s/(.*)/()/;p}'
LIST = ()
if you could use awk, this one-liner works for your example too:
awk -v RS="" '{sub(/\(.*\)/,"()")}1'
test:
kent$ echo 'LIST = ( "content"
"content1"
"content3")'|awk -v RS="" '{sub(/\(.*\)/,"()")}1'
LIST = ()
EDIT for OP's comment
multi brackets situation:
awk
awk -v RS="\0" -v ORS="" '{gsub(/LIST\s*=\s*\([^)]*\)/,"LIST = ()")}1' file
test:
kent$ cat file
LISTKEEP2("CONTENT")
LIST = ( "content"
"content1"
"content3")
LISTNUMBER2("CONTENT")
kent$ awk -v RS="\0" -v ORS="" '{gsub(/LIST\s*=\s*\([^)]*\)/,"LIST = ()")}1' file
LISTKEEP2("CONTENT")
LIST = ()
LISTNUMBER2("CONTENT")
sed:
sed -nr '1!H;1h;${x;s/(LIST\s*=\s*\()[^)]*\)/\1)/;p}' file
kent$ sed -nr '1!H;1h;${x;s/(LIST\s*=\s*\()[^)]*\)/\1)/;p}' file
LISTKEEP2("CONTENT")
LIST = ()
LISTNUMBER2("CONTENT")

Another sed solution:
sed '/LIST = (/{:next;/)/{s/(.*)/()/;b;};N;b next;}'
Here's a version that would not change any block containing a certain string ("keepme" in this example, but could be anything):
sed '/LIST = (/{:next;/)/{/keepme/b;s/(.*)/()/;b;};N;b next;}'
Since this does the keepme test after it finds the closing parenthesis that tag can be anywhere in the block.

Related

Print pattern on a string with special character

How to print only string figure with the following line :
\begin{figure}[h!]
I tried :
firstLine='\begin{figure}[h!]'
echo $firstLine | sed -n 's/\\begin{\(.*\)}/\1/p'
but returns :
figure[h!] instead of figure
It seems that issue comes from [] or ! character.
firstLine='\begin{figure}[h!]'
echo "$firstLine" | sed 's/.*{\(.*\)}.*/\1/'
Output:
figure
With your code (add .*):
echo $firstLine | sed -n 's/\\begin{\(.*\)}.*/\1/p'
This might work for you (GNU sed):
sed 's/.*{\(.*\)}.*/\1/' file
This assumes there is only one {...} expression and one line.
A more rigorous solution would be:
sed -n 's/.*\\begin{\([^}]*\)}.*/\1/p' file
However nothing would be output if no match was found.

replace a line that contains a string with special characters

i want to replace lines which contains a string that has some special characters.
i used \ and \ for escape special characters but nothing changes in file.
i use sed like this:
> sed -i '/pnconfig\[\'dbhost\'\] = \'localhost\'/c\This line is removed.' tco.php
i just want to find lines that contains :
$pnconfig['dbhost'] = 'localhost';
and replace that line with:
$pnconfig['dbhost'] = '1.1.1.1';
Wrap the sed in double quotes as
sed -i "s/\(pnconfig\['dbhost'\] = \)'localhost'/\1'1.1.1.1'/" filename
Test
$ echo "\$pnconfig['dbhost'] = 'localhost';" | sed "s/\(pnconfig\['dbhost'\] = \)'localhost'/\1'1.1.1.1'/"
$pnconfig['dbhost'] = '1.1.1.1';
Use as below:
sed -i.bak '/pnconfig\[\'dbhost\'\] = \'localhost\'/pnconfig\[\'dbhost\'\] = \'1.1.1.1\'/' tco.php
Rather than modifying the file for the first time, create back up and then search for your pattern and then replace it with the other as above in your file tco.php
You don't have to worry about backslashing single quotes by using double quotes for sed.
sed -i.bak "/pnconfig\['dbhost'\] = 'localhost'/s/localhost/1.1.1.1/g" File
Try this one.
sed "/$pnconfig\['dbhost']/s/localhost/1.1.1.1/"

Extract data between two strings using either AWK or SED

I'm trying to extract data/urls (in this case - someurl) from a file that contains them within some tag ie.
xyz>someurl>xyz
I don't mind using either awk or sed.
I think the best, easiest, way is with cut:
$ echo "xyz>someurl>xyz" | cut -d'>' -f2
someurl
With awk can be done like:
$ echo "xyz>someurl>xyz" | awk 'BEGIN { FS = ">" } ; { print $2 }'
someurl
And with sed is a little bit more tricky:
$ echo "xyz>someurl>xyz" | sed 's/\(.*\)>\(.*\)>\(.*\)/\2/g'
someurl
we get blocks of something1<something2<something3 and print the 2nd one.
grep was born to extract things:
kent$ echo "xyz>someurl>xyz"|grep -Po '>\K[^>]*(?=>)'
someurl
you could kill a fly with a bomb of course:
kent$ echo "xyz>someurl>xyz"|awk -F\> '$0=$2'
someurl
If your grep supports P option then you can use lookahead and lookbehind regular expression to identify the url.
$ echo "xyz>someurl>xyz" | grep -oP '(?<=xyz>).*(?=>xyz)'
someurl
This is just a sample to get you started not the final answer.

Unix - Removing everything after a pattern using sed

I have a file which looks like below:
memory=500G
brand=HP
color=black
battery=5 hours
For every line, I want to remove everything after = and also the =.
Eventually, I want to get something like:
memory:brand:color:battery:
(All on one line with colons after every word)
Is there a one-line sed command that I can use?
sed -e ':a;N;$!ba;s/=.\+\n\?/:/mg' /my/file
Adapted from this fine answer.
To be frank, however, I'd find something like this more readable:
cut -d = -f 1 /my/file | tr \\n :
Here's one way using GNU awk:
awk -F= '{ printf "%s:", $1 } END { printf "\n" }' file.txt
Result:
memory:brand:color:battery:
If you don't want a colon after the last word, you can use GNU sed like this:
sed -n 's/=.*//; H; $ { g; s/\n//; s/\n/:/g; p }' file.txt
Result:
memory:brand:color:battery
This might work for you (GNU sed):
sed -i ':a;$!N;s/=[^\n]*\n\?/:/;ta' file
perl -F= -ane '{print $F[0].":"}' your_file
tested below:
> cat temp
abc=def,100,200,dasdas
dasd=dsfsf,2312,123,
adasa=sdffs,1312,1231212,adsdasdasd
qeweqw=das,13123,13,asdadasds
dsadsaa=asdd,12312,123
> perl -F= -ane '{print $F[0].":"}' temp
abc:dasd:adasa:qeweqw:dsadsaa:
My command is
First step:
sed 's/([a-z]+)(\=.*)/\1:/g' Filename |cat >a
cat a
memory:
brand:
color:
battery:
Second step:
sed -e 'N;s/\n//' a | sed -e 'N;s/\n//'
My output is
memory:brand:color:battery:

How can I add the current date or time to end of each line in file?

I have a file called data.txt.
I want to add the current date, or time, or both to the beginning or end of each line.
I have tried this:
awk -v v1=$var ' { printf("%s,%s\n", $0, v1) } ' data.txt > data.txt
I have tried this:
sed "s/$/,$var/" data.txt
Nothing works.
Can someone help me out here?
How about :
cat filename | sed "s/$/ `date`/"
The problem with this
awk -v v1=$var ' { printf("%s,%s\n", $0, v1) } ' data.txt > data.txt
is that the > redirection happens first, and the shell truncates the file. Only then does the shell exec awk, which then reads an empty file.
Choose one of these:
sed -i "s/\$/ $var/" data.txt
awk -v "date=$var" '{print $0, date}' data.txt > tmpfile && mv tmpfile data.txt
However, does your $var contain slashes (such as "10/04/2011 12:34") ? If yes, then choose a different delimiter for sed's s/// command: sed -i "s#\$# $var#" data.txt