
Tenho uma variável atribuída a uma string retornada:
ytd_wk=$(cat file.csv | grep $(date +'%Y') | tail -1)
Quero substring os últimos 2 caracteres:
ytd_wk=${ytd_wk:(-2)}
Existe alguma maneira de usar uma linha para conseguir isso? Eu tentei abaixo, mas recebi bad substitution
um erro:
ytd_wk=${$(cat file.csv | grep $(date +'%Y') | tail -1):(-2)}
Responder1
Tente usar:
grep "$(date +'%Y')" file.csv | tail -1 | sed 's/.*\(..$\)/\1/'
Você não precisa cat
porque grep
pode obter dados da saída de outro programa ou de determinado arquivo. O último método é mais eficiente porque utiliza apenas um comando e este é mais rápido e consome menos recursos do sistema.
A solução completa:
ytd_wk=$(grep "$(date +'%Y')" file.csv | tail -1 | sed 's/.*\(..$\)/\1/')
Você pode omitir tail
com 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/'
Responder2
Você poderia usar awk
, combinando cat
, grep
, sed
e tail
de outras sugestões:
awk -v year=$(date +'%Y') '$0 ~ year {line=$0} END {print substr(line,length(line)-1,2)}' file.csv
Escrevendo isso passo a passo
-v year=$(date +'%Y')
define aawk
variávelyear
para o ano atual$0 ~ year { line=$0 }
isso é aplicado a cada linha do arquivo por vez. Se houver uma correspondência com o ano na linha atual ele salva naawk
variávelline
END { print substr(line,length(line)-1,2) }
no final do arquivo (após a última linha ter sido lida e processada), imprime os dois últimos caracteres da linha salva mais recentemente. Ele imprime uma linha em branco se não houve nenhuma correspondência anterior bem-sucedida.
Responder3
Isto é mais eficiente, especialmente searquivo.csvé grande e a linha desejada está mais próxima do final:
ytd_wk="$(tac file.csv | grep -m 1 $(date +'%Y') | grep -o '..$')"
Como funciona: tac
saídasarquivo.csvpara trás e grep -m 1
encontra a primeira instância do padrão, que é alimentada e grep -o
gera apenas os dois últimos caracteres.