Wenn die Ausgabe des cal
Befehls kein Terminal ist, wird die Unterstreichung des armen Mannes auf die Tageszahl für heute angewendet, die darin besteht, vor jedem Zeichen einen Unterstrich und ein Rücktastezeichen zu setzen, um sie zu unterstreichen. Sie können dies sehen, indem Sie die Zeichen visuell anzeigen ( ^H
bedeutet Steuerelement-H , das Rücktaste-Zeichen):
cal | cat -A
cal | cat -vet
oder indem Sie sich einen Hex-Dump ansehen:
cal | hd
cal | od -t x1
Sie müssen also die unterstrichenen Zeichen erkennen und ausgeben.
Mit GNU grep können Sie auf einfache Weise alle Übereinstimmungen eines regulären Ausdrucks drucken: Verwenden Sie die -o
Option. Ein Unterstreichungszeichen wird durch den erweiterten regulären Ausdruck abgeglichen, _^H.
wobei ^H
es sich um ein wörtliches Rücktastezeichen handelt, nicht um die beiden Zeichen ^
und H
, und .
das zu druckende Zeichen. Anstatt das Rücktastezeichen einzugeben, können Sie sich darauf verlassen, dass nur so Unterstriche in der Ausgabe verwendet werden. Es reicht also aus, die Unterstriche zu erkennen und die Rückräume als nicht übereinstimmende Zeichen zu belassen.
cal | grep -o '_..'
Wir sind nah dran, aber die Ausgabe enthält die Unterstrich-Backslash-Sequenz und die Ziffern stehen in separaten Zeilen. Sie können alle nichtstelligen Zeichen entfernen (und eine nachfolgende neue Zeile hinzufügen):
cal | grep -o '_..' | tr -d 0-9; echo
Alternativ können Sie das Muster wiederholen _..
, um mehrere unterstrichene Ziffern abzugleichen. Dadurch bleibt die Unterstreichung in der Ausgabe erhalten. Sie können tr oder sed verwenden, um sie zu entfernen.
cal | grep -E -o '(_..)*'
cal | grep -E -o '(_..)*' | tr -d '\b_'
cal | grep -E -o '(_..)*' | sed 's/_.//g'
Sie können dies mit sed tun, aber es ist nicht ganz einfach. Sed bietet eine einfache Möglichkeit, nur übereinstimmende Zeilen zu drucken (verwenden Sie die -n
Option, um nur Zeilen abzurufen, die explizit gedruckt werden), aber keine direkte Möglichkeit, mehrere Vorkommen einer Übereinstimmung in einer Zeile zu drucken. Eine Möglichkeit, dies zu lösen, besteht darin, die Tatsache auszunutzen, dass höchstens zwei unterstrichene Zeichen vorhanden sind und einen s
Befehl zum Transformieren und Ausgeben von Zeilen mit einem einzelnen unterstrichenen Zeichen und einen anderen für Zeilen mit zwei Zeichen haben. Nach wie vor werde ich die Backspaces nicht explizit abgleichen.
cal | sed -n 's/.*_.\(.\)_.\(.\).*/\1\2/p; s/.*_.\(.\).*/\1/p'
Ein alternativer Ansatz mit sed unter der Annahme, dass es nur ein unterstrichenes Segment in einer Linie gibt, besteht darin, alles davor und alles danach zu entfernen.
cal | sed -n 's/^[^_]*_/_/; s/\(_..\)[^_]*$/\1/p'
Dies hinterlässt die Unterstriche; Wir können sie mit einem dritten Ersatz entfernen.
cal | sed -n 's/^[^_]*_/_/; s/\(_..\)[^_]*$/\1/; s/_.//gp'