Variablensubstitution

Variablensubstitution

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 substitutionein 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, catweil grepSie 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/')

tailMit 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 awkund dabei die cat, grep, sed, und tailanderer 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 die awkVariable yearauf 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 der awkVariablen 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: tacAusgängeDatei.csvrückwärts und grep -m 1findet die erste Instanz des Musters, das weitergeleitet wird grep -ound nur die letzten beiden Zeichen ausgibt.

verwandte Informationen