4

I was looking for a command which will print the selected portion of a line which matches the conditions. Eg, my text line is like this:

p1=X||p2=Y||p3=X||p4=X||p5=X||p6=Y||p7=X

I want to print those values that have have Y. With this example, the expected result is p2,p6.

  • Do you want to print p2,p6, or p2 newline p6, or p2=Y newline p6=Y? If there was p8=YZ, would you want to print p8? – Gilles Jul 28 '15 at 22:48
7

Using Perl compatible regular expression in grep:

grep -Po '..(?==Y)' <file

Result:

p2
p6
  • 2
    and the code golf winner is ... – Archemar Jul 28 '15 at 10:17
3

Try this:

echo 'p1=X||p2=Y||p3=X||p4=X||p5=X||p6=Y||p7=X' | grep -o '[^|]*=Y' | cut -d= -f1 | sed -e 'N;s/\n/,/g'

Output:

p2,p6
2

awk can read records based on a regex delimiter of your choice. eg '[|\n]'
It can also split records into fields on the delimeter of your choice. eg. '='
The ternary operator (condition)?: prevents a leading comma.

awk -F= -vRS='[|\n]' '$2=="Y"{ printf (i?",":"")"%s", $1; i=1 }'

output:

p2,p6

If a trailing newline is needed, it can be appended in the END{} section. To prevent a newline being output when there are no matches, the Output Record Separator (ORS) can be initially set to none, and then set to \n if a match is found.

awk -F= -vRS='|' -vORS= '$2=="Y"{printf (ORS?",":"")"%s", $1; ORS="\n"} END{print ""}'
2

How about:

tr '|' '\n' | sed -n 's/=Y$//p'
1

a simple awk

awk -F\| '{for (i=1 ; i<= NF; i++) 
    if ( $i ~/Y/ ) { split($i,A,"=") ; printf "in %d : %s\n",i,A[1] ;}}'

where

  • -F\| use | as separator
  • {for (i=1 ; i<= NF; i++) scan through pattern
  • if ( $i ~/Y/ ) if found
  • { split($i,A,"=") ; printf "in %d : %s\n",i,A[1] ;} split it and print it

output

in 3 : p2
in 11 : p6

use printf "%s\n",A[1] to skip pattern number

1
perl -nE 'say join(",",/(\w+)=Y/g)'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.