Reputation: 23
I have a text file with a random number of lines. Lines look like this:
neededLine [text1] sometext [text2] sometext [text3]
sometext [text4] sometext [text5] sometext [text6]
neededLine [text7] sometext [text8] sometext [text9]
I have a grep command in shell, which takes lines with 'neededLine' word, and then extracts everything inside brackets.
Command looks like this:
grep 'neededLine' |grep -Po '(?<=\[).*?(?=\])' | tr '\n' ' '
So my output looks like this:
text1 text2 text3 text7 text8 text9
If I remove tr
, output starts with a new line for every single word:
text1
text2
text3
...
How do I get an output, which prints the result in one separate line for every single input line? It should look like
text1 text2 text3
text7 text8 text9
Upvotes: 2
Views: 238
Reputation: 50750
With sed:
sed '/neededLine/!d
s/[^[]*\[//
s/\][^[]*$//
s/\][^[]*\[/ /g' file
Upvotes: 2
Reputation: 133458
Could you please try following, written and tested with shown samples in GNU awk
.
awk '
/neededLine/{
while(match($0,/\[[^]]*/)){
val=(val?val OFS:"")substr($0,RSTART+1,RLENGTH-1)
$0=substr($0,RSTART+RLENGTH+1)
}
print val
val=""
}
' Input_file
Explanation: Adding detailed explanation for above.
awk ' ##Starting awk program from here.
/neededLine/{ ##Checking if a line starts with neededLine then do following.
while(match($0,/\[[^]]*/)){ ##Using regex in match function till its result comes true in current line.
val=(val?val OFS:"")substr($0,RSTART+1,RLENGTH-1) ##Creating var val whose value keep concatenate its own value and its value is sub-string of current line.
$0=substr($0,RSTART+RLENGTH+1) ##Assigning sub-string value to current line which will be rest of the line after matching above.
}
print val ##Printing val here.
val="" ##Nullifying val here.
}
' Input_file ##Mentioning Input_file name here.
Upvotes: 2
Reputation: 23667
With perl
:
$ perl -lne 'print join " ", /\[\K.*?(?=])/g if /neededLine/' ip.txt
text1 text2 text3
text7 text8 text9
if /neededLine/
only lines containing neededLine
/\[\K.*?(?=])/g
extract contents between [
and ]
\K
is helpful to discard text matched until that point/\[\K[^]]+(?=])/g
join " "
to combine the matched portions with a space-l
option removes the record separator and adds it back at the end of print
statement, helps to get a newline character in this case
Another solution with GNU awk
$ awk -v FPAT='\\[[^]]+]' '/neededLine/{for(i=1;i<=NF;i++)
gsub(/^.|.$/, "", $i); print}' ip.txt
text1 text2 text3
text7 text8 text9
Upvotes: 2