
Ich habe einer zurückgegebenen Zeichenfolge eine Variable zugewiesen:
ytd_wk=$(cat file.csv | grep $(date +'%Y') | tail -1)
Ich möchte die letzten beiden Zeichen in einen Teilstring unterteilen:
ytd_wk=${ytd_wk:(-2)}
Gibt es eine Möglichkeit, dies mit einem Einzeiler zu erreichen? Ich habe Folgendes versucht, aber es ist bad substitution
ein Fehler aufgetreten:
ytd_wk=${$(cat file.csv | grep $(date +'%Y') | tail -1):(-2)}
Antwort1
Versuchen zu benutzen:
grep "$(date +'%Y')" file.csv | tail -1 | sed 's/.*\(..$\)/\1/'
Sie brauchen das nicht, cat
weil grep
Sie Daten sowohl aus der Ausgabe eines anderen Programms als auch aus einer bestimmten Datei abrufen können. Die letzte Methode ist effizienter, weil sie nur einen Befehl verwendet und schneller ist und weniger Systemressourcen verbraucht.
Die vollständige Lösung:
ytd_wk=$(grep "$(date +'%Y')" file.csv | tail -1 | sed 's/.*\(..$\)/\1/')
tail
Mit GNU können Sie Folgendes weglassen sed '$!d'
:
grep "$(date +'%Y')" file.csv | sed -r '$!d;s/.*(..$)/\1/'
POSIX:
grep "$(date +'%Y')" file.csv | sed -e '$!d' -e 's/.*\(..$\)/\1/'
Antwort2
Sie könnten verwenden awk
und dabei die cat
, grep
, sed
, und tail
anderer Vorschläge kombinieren:
awk -v year=$(date +'%Y') '$0 ~ year {line=$0} END {print substr(line,length(line)-1,2)}' file.csv
Schritt für Schritt aufschreiben
-v year=$(date +'%Y')
setzt dieawk
Variableyear
auf das aktuelle Jahr$0 ~ year { line=$0 }
Dies wird nacheinander auf jede Zeile der Datei angewendet. Wenn es eine Übereinstimmung mit dem Jahr in der aktuellen Zeile gibt, wird diese in derawk
Variablen gespeichertline
END { print substr(line,length(line)-1,2) }
Am Ende der Datei (nachdem die letzte Zeile gelesen und verarbeitet wurde) werden die letzten beiden Zeichen der zuletzt gespeicherten Zeile gedruckt. Wenn zuvor keine erfolgreiche Übereinstimmung gefunden wurde, wird eine leere Zeile gedruckt.
Antwort3
Dies ist effizienter, insbesondere wennDatei.csvist groß und die gewünschte Zeile liegt näher am Ende:
ytd_wk="$(tac file.csv | grep -m 1 $(date +'%Y') | grep -o '..$')"
So funktioniert es: tac
AusgängeDatei.csvrückwärts und grep -m 1
findet die erste Instanz des Musters, das weitergeleitet wird grep -o
und nur die letzten beiden Zeichen ausgibt.