変数の置換

変数の置換

返された文字列に変数が割り当てられています。

ytd_wk=$(cat file.csv | grep $(date +'%Y') | tail -1)

最後の2文字を部分文字列で囲みたいです。

ytd_wk=${ytd_wk:(-2)}

1行でこれを達成する方法はありますか?以下を試しましたが、bad substitutionエラーが発生しました。

ytd_wk=${$(cat file.csv | grep $(date +'%Y') | tail -1):(-2)}

答え1

以下を試してください。

grep "$(date +'%Y')" file.csv | tail -1 | sed 's/.*\(..$\)/\1/'

他のプログラムの出力や一部のファイルからデータを取得できるため、cat必要はありません。grep最後の方法は、1つのコマンドのみを使用し、より速く、システムリソースを消費しにくく、より効率的です。

完璧なソリューション:

ytd_wk=$(grep "$(date +'%Y')" file.csv | tail -1 | sed 's/.*\(..$\)/\1/')

tailGNU省略を使用できますsed '$!d'

grep "$(date +'%Y')" file.csv | sed -r '$!d;s/.*(..$)/\1/'

POSIX:

grep "$(date +'%Y')" file.csv | sed -e '$!d' -e 's/.*\(..$\)/\1/'

答え2

、他の提案、とawk一緒に使用することができます。catgrepsedtail

awk -v year=$(date +'%Y') '$0 ~ year {line=$0} END {print substr(line,length(line)-1,2)}' file.csv

この手順を段階的に作成してください。

  • -v year=$(date +'%Y')awkyear変数を今年に設定
  • $0 ~ year { line=$0 }これはファイルの各行に順番に適用されます。現在行の年と一致する項目がある場合は、awk変数に保存します。line
  • END { print substr(line,length(line)-1,2) }ファイルの最後に(最後の行を読み取って処理した後)、最後に保存された行の最後の2文字を印刷します。以前に成功した一致がない場合は、空白行が印刷されます。

答え3

特に、次のような場合、これはより効率的です。ファイル.csv大きくて必要な行が最後に近いです。

ytd_wk="$(tac file.csv | grep -m 1 $(date +'%Y') | grep -o '..$')"

仕組み: tac出力ファイル.csv後ろに移動して、最後の2文字だけを出力するように指定されたパターンgrep -m 1の最初のインスタンスを見つけます。grep -o

関連情報