
我有一個變數分配給返回的字串:
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
僅輸出最後兩個字元。