2016-11-18 4 views
0

Ich versuche, die aktuellen Titel von ‚cmus-remote -Q‘ Laufen zu bekommen Sein immer unterhalb dieser LinieBash - grep nur die Zeile nach

tag genre Various 
<some track> 

Nun, ich brauche es einfach zu halten weil ich es zu meiner i3 Bar hinzufügen möchte.

I verwendet

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

aber das grep ist die 'Tag' Linie und die unter Leitung.

Ich möchte nur die Linie darunter.

+0

Was ist nur die RE mit einem anderen Rohr ohne? 'cmus-remote -Q | grep -A 1 "Taggenre" | grep -v "tag genre" '? Es scheitert natürlich, wenn der RE auf zwei Zeilen hintereinander steht. – ghoti

+0

Wenn Ihr 'grep'' -P' Option unterstützt, dann ist es so einfach, 'grep-oPz 'Taggenre. * \ N \ K. *' Datei' –

Antwort

0

gedruckt werden wenn Sie grep als Werkzeug dafür verwenden möchten, können Sie es erreichen, indem ein anderes Segment der Pipeline ergänzt:

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

Dies wird in Fällen fehlschlagen, wenn die Zeichenfolge die Sie suchen auf zwei Zeilen i in einer Reihe. Sie müssen definieren, welches Verhalten Sie in diesem Fall wünschen, wenn wir etwas Sinnvolles dafür programmieren wollen.

Eine andere Möglichkeit wäre, ein Tool wie awk zu verwenden, die für eine größere Komplexität im in der Linie Auswahl erlaubt:

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

Diese für die Zeichenfolge sucht, wird dann die nächste Zeile, druckt es dann.

Eine andere Möglichkeit wäre dies allein in bash zu tun:

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

Dies implementiert die gleiche Funktionalität wie die awk-Skript, erst gar keine externen Tools. Es ist wahrscheinlich langsamer als das Awk-Skript.

0

können Sie awk anstelle von grep:

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

<some track> 
  • /tag genre/{p=1} - setzt ein Flag p=1 wenn es tag genre in einer Linie trifft.
  • p{print; p=0} Wenn nicht Null ist, druckt es eine Zeile und setzt auf 0 zurück.
+0

Danke, das funktioniert auch, aber ich denke das grep -v , Ist einfach einfacher: < – KeVy0

+1

Hmm aber das ruft 2 Befehle auf statt nur einer mit awk – anubhava

+1

Ok, fair genug :). Danke – KeVy0

0

Ich würde vorschlagen, awk mit:

awk 'seen && seen--; /tag genre/ { seen = 1 }' 
  • wenn seen wahr ist, die Zeile drucken.
  • wenn seen wahr ist, um den Wert dekrementieren, so wird es nicht mehr wahr, nachdem die gewünschte Anzahl von Zeilen gedruckt ist
  • wenn das Muster übereinstimmt, gesetzt seen auf die Anzahl der Zeilen
0

Mit sed:

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

Ausgang:

$ cmus-remote -Q | sed -n '/tag genre/{n;p}' 
<some track>