How to print matching pattern only

Viewed 135

I need to print [PR:XXXXX] only.

Ex: [Test][PR:John][Finished][Reviewer:SE] to [PR:John] only. (PR tag)

Note:Other strings rather than the [PR:XXXXX] may changed time to time Ex:

[Test][PR:Cook][Completed]
[Test][Finished][PR:Russell][Reviewer:SE]
[Dump][Reviewer:SE][Complete][PR:Arnold]

Note: There are no multi line inputs and only one PR tag is included in all of inputs.

Untill I create following sed command but it did not work:

sed "s/\[PR:[^]]*\]//"
7 Answers

You might use bash for this:

s='[Test][PR:Cook][Completed]'
regex='\[PR:[^]]*]'
[[ "$s" =~ $regex ]] && echo "${BASH_REMATCH[0]}"
# => [PR:Cook]

See this online demo.

You may use grep:

grep -o '\[PR:[^]]*]'

See this demo.

Or, you can use this sed:

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

See this online demo.

Or, you can use awk

awk 'match($0,/\[PR:[^]]*]/) {print substr($0,RSTART,RLENGTH)}'

See the online demo.

If you only have 1 such field max per line and want a blank line printed if no such field exists on the line then using GNU awk for FPAT:

$ awk -v FPAT='[[]PR:[^]]+]' '{print $1}' file
[PR:Cook]
[PR:Russell]
[PR:Arnold]

If you can have 0 to N such fields per line, e.g.:

$ cat file
[Test][PR:Cook][Completed]
[Test][Finished][PR:Russell][Reviewer:SE]
[Test][Finished][Reviewer:SE]
[Test][Finished][PR:Jack][PR:Russell][Reviewer:SE]
[Dump][Reviewer:SE][Complete][PR:Arnold]

then here's some of the options depending on your requirements:

$ awk -v FPAT='[[]PR:[^][]+]' '{print $1}' file
[PR:Cook]
[PR:Russell]

[PR:Jack]
[PR:Arnold]

$ awk -v FPAT='[[]PR:[^][]+]' 'NF{print $1}' file
[PR:Cook]
[PR:Russell]
[PR:Jack]
[PR:Arnold]

$ awk -v FPAT='[[]PR:[^][]+]' '{for (i=1; i<=NF; i++) print $i}' file
[PR:Cook]
[PR:Russell]
[PR:Jack]
[PR:Russell]
[PR:Arnold]

$ awk -v FPAT='[[]PR:[^][]+]' '{$1=$1} 1' file
[PR:Cook]
[PR:Russell]

[PR:Jack] [PR:Russell]
[PR:Arnold]

If you have more than 1 occurrences of [PR to be printed in a single line then try following.

awk '{while(match($0,/\[PR:[^]]*\]/)){print substr($0,RSTART,RLENGTH);$0=substr($0,RSTART+RLENGTH)}}' Input_file

Simple explanation would be, using match function of awk to find all blocks which have [PR.....] in them, then printing all occurrences until all are printed in each line.

Use this perl command line:

perl -pe 's/\[[^P][^R][^:].*?\]//g' your_file

Test Below:

$ echo "[Test][Finished][PR:Russell][Reviewer:SE][PR:Rachel]"|perl -pe 's/\[[^P][^R][^:].*?\]//g'
[PR:Russell][PR:Rachel]

Another perl:

perl -lne 'print join "", grep {/^\[PR:/} /\[.+?\]/g' file

This will accomodate multiple PR tags on one line.

Here is a a shorter gnu-awk solution (using same input file as in Ed's answer):

awk -v RS='\\[PR:[^]]+]' 'RT {print RT}' file

[PR:Cook]
[PR:Russell]
[PR:Jack]
[PR:Russell]
[PR:Arnold]

Here is a Ruby:

ruby -lne 'puts $_.scan(/\[PR.+?\]/).join("")' file

This accommodates multiple PR tags per line.

Related