1

I'm trying to get the current track running from 'cmus-remote -Q' Its always underneath of this line

 tag genre Various
 <some track>

Now, I need to keep it simple because I want to add it to my i3 bar. I used

cmus-remote -Q | grep -A 1 "tag genre" 

but that grep's the 'tag' line AND the line underneath.

I want ONLY the line underneath.

jww
  • 97,681
  • 90
  • 411
  • 885
KeVy0
  • 15
  • 1
  • 5
  • What about just excluding the RE with another pipe? `cmus-remote -Q | grep -A 1 "tag genre" | grep -v "tag genre"` ? It fails if the RE is on two lines in a row, of course. – ghoti Nov 18 '16 at 11:51
  • If your `grep` supports `-P` option then it's so simple, `grep -oPz 'tag genre.*\n\K.*' file` – Avinash Raj Nov 18 '16 at 12:01

4 Answers4

2

With sed:

sed -n '/tag genre/{n;p}'

Output:

$ cmus-remote -Q | sed -n '/tag genre/{n;p}'
<some track>
sat
  • 14,589
  • 7
  • 46
  • 65
1

You can use awk instead of grep:

awk 'p{print; p=0} /tag genre/{p=1}' file

<some track>
  • /tag genre/{p=1} - sets a flag p=1 when it encounters tag genre in a line.
  • p{print; p=0} when p is non-zero then it prints a line and resets p to 0.
anubhava
  • 761,203
  • 64
  • 569
  • 643
1

If you want to use grep as the tool for this, you can achieve it by adding another segment to your pipeline:

cmus-remote -Q | grep -A 1 "tag genre" | grep -v "tag genre"

This will fail in cases where the string you're searching for is on two lines in a row. You'll have to define what behaviour you want in that case if we're going to program something sensible for it.

Another possibility would be to use a tool like awk, which allows for greater compexity in the line selection:

cmus-remote -Q | awk '/tag genre/ { getline; print }'

This searches for the string, then gets the next line, then prints it.

Another possibility would be to do this in bash alone:

while read line; do
  [[ $line =~ tag\ genre ]] && read line && echo "$line"
done < <(cmus-remote -Q)

This implements the same functionality as the awk script, only using no external tools at all. It's likely slower than the awk script.

ghoti
  • 45,319
  • 8
  • 65
  • 104
0

I'd suggest using awk:

awk 'seen && seen--; /tag genre/ { seen = 1 }'
  • when seen is true, print the line.
  • when seen is true, decrement the value, so it will no longer true after the desired number of lines are printed
  • when the pattern matches, set seen to the number of lines to be printed
Tom Fenech
  • 72,334
  • 12
  • 107
  • 141