返された文字列に変数が割り当てられています。
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/')
tail
GNU省略を使用できます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
一緒に使用することができます。cat
grep
sed
tail
awk -v year=$(date +'%Y') '$0 ~ year {line=$0} END {print substr(line,length(line)-1,2)}' file.csv
この手順を段階的に作成してください。
-v year=$(date +'%Y')
awk
year
変数を今年に設定$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