变量替换

变量替换

我有一个变量分配给返回的字符串:

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

我想对最后 2 个字符进行子串:

ytd_wk=${ytd_wk:(-2)}

有没有办法使用单行来实现这一目标?我已尝试以下但出现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可以从另一个程序的输出或某个文件中获取数据。最后一种方法更有效,因为它只使用一个命令,速度更快,消耗的系统资源更少。

完整的解决方案:

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,结合其他建议的catgrepsedtail

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) }在文件末尾(在读取并处理最后一行之后),这会打印最近保存的行的最后两个字符。如果没有先前的成功匹配,它将打印一个空行。

答案3

这更有效,特别是如果文件.csv很大并且所需的线更接近末端:

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

工作原理: tac输出文件.csv向后,并grep -m 1找到模式的第一个实例,该实例被馈送到grep -o仅输出最后两个字符。

相关内容