我有一个变量分配给返回的字符串:
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
,结合其他建议的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) }
在文件末尾(在读取并处理最后一行之后),这会打印最近保存的行的最后两个字符。如果没有先前的成功匹配,它将打印一个空行。
答案3
这更有效,特别是如果文件.csv很大并且所需的线更接近末端:
ytd_wk="$(tac file.csv | grep -m 1 $(date +'%Y') | grep -o '..$')"
工作原理: tac
输出文件.csv向后,并grep -m 1
找到模式的第一个实例,该实例被馈送到grep -o
仅输出最后两个字符。