1
votes

I have some text as below:

path => ["/home/Desktop/**/auditd.log",
        "/home/Desktop/**/rsyslog*.log",
        "/home/Desktop/**/snmpd.log",
        "/home/Desktop/**/kernel.log",
        "/home//Desktop/**/ntpd.log",
        "/home/Desktop/**/mysql*.log",
        "/home/Desktop/**/sshd.log",
        "/hme/Desktop/**/su.log",
        "/home/Desktop/**/run-parts(.log"
    ] 

I want to extract the values inside [ ], so I am doing:

sed -n 's/.*\[\(.*\)\]/\1/p'

Sed is not returning anything.

If I do sed -n 's/.*\[\(.*\)log/\1/p it's returning properly the string between [ and log.

"/home/Desktop/**/auditd.",

So it's able to search within the line.

How to make this work??

EDIT:

I created a file with content:

path => [asd,masd,dasd
sdalsd,ad
asdlmas;ldasd
]

When I do grep -o '\[.*\]' it does not work but grep -o '\[.*' this returns the 1st line [asd,masd,dasd. So it's working for single line not for multiple lines.

4
sed is line-oriented. Your first pattern doesn't match on any of the lines in your input.Etan Reisner
So how to extract multiple lines if one has to ?? Grep also returns searches on same lineSiddharth Trikha
If you need to match contents between lines use something like awk or some tool that can actually understand the input format. The last bit of this question shows you a very handy awk pattern for range-of-line processing.Etan Reisner
I did use awk: awk '/\[/,/\]/' but it's returning an output which is same as input as it's including path => in the outputSiddharth Trikha
This file is the output of what ? Seems a Data StructureGilles Quenot

4 Answers

1
votes

Try doing this :

$ grep -o '".*",?' file

OUTPUT:

"/home/Desktop/**/auditd.log",
"/home/Desktop/**/rsyslog*.log",
"/home/Desktop/**/snmpd.log",
"/home/Desktop/**/kernel.log",
"/home//Desktop/**/ntpd.log",
"/home/Desktop/**/mysql*.log",
"/home/Desktop/**/sshd.log",
"/hme/Desktop/**/su.log",
"/home/Desktop/**/run-parts(.log"
  • -o for grep print only the matching part
  • " is a literal double quote
  • .* is anything
  • " si the closing double quote
  • , is a literal double quote
  • ? mean o or 1 occurrence
1
votes

Well, I was a bit too slow, but I think the question of how to apply sed substitutions to a whole file as a block rather than on a line-by-line basis merits a general answer, so I'll leave one here.

In your specific case, you could use this pattern:

sed -n 'H; $ { x; s/.*\[\(.*\)\].*/\1/; p; }' foo.txt

The general trick is

sed -n 'H; $ { x; s/pattern/replacement/flags; p; }' file

What this means is: Every line that comes in is appended to the hold buffer (with the H command), and at the end of the file ($), when the whole file is in the hold buffer, the stuff between the brackets is executed. In that block, the hold buffer is swapped with the pattern space (x), then the substitution is done, and what remains in the pattern space is printed (p).

EDIT: One caveat of this simple form is that it doesn't work properly if your pattern wants to match the beginning of the file; for reasons the hold buffer is not entirely empty when sed is first called (it contains an empty line). If this is important, the slightly more complicated form

sed -n '1 h; 1 !H; $ { x; s/pattern/replacement/flags; p; }' file

fixes it. This will use h instead of H for the first line, which overwrites the hold buffer with the pattern space rather than appending the pattern space to the hold buffer.

0
votes

You can do it with awk by replacing .*[ or ] or white spaces with nothing:

$ awk '{gsub(/.*\[|\]| /, ""); print}' filename

"/home/Desktop/**/auditd.log",
"/home/Desktop/**/rsyslog*.log",
"/home/Desktop/**/snmpd.log",
"/home/Desktop/**/kernel.log",
"/home//Desktop/**/ntpd.log",
"/home/Desktop/**/mysql*.log",
"/home/Desktop/**/sshd.log",
"/hme/Desktop/**/su.log",
"/home/Desktop/**/run-parts(.log"
0
votes

from your sample, it could also be (treat only first and last line)

sed '1s/^[^[]*\[//;$d' YourFile