Para começar, o que você dá não é uma afirmação. É um monte de comandos encadeados através de Pipes e Comando de substituição .
grep 'date +%Y-%m-%d --date='1 day ago'' /path/to/file/FILE_PREFIX_\'date +%Y%m%d --date='1 day ago''.dsv | grep -v 'ERROR' | cut -d "|" -f 2 | sed 's/^0/27/'
Vamos separá-los um por um.
Substituição de Comando
-
date +%Y-%m-%d --date='1 day ago'
aparece duas vezes e mostra a data de ontem no formato YYYY-mm-dd
(por exemplo, 2015-07-31)
- A segunda chamada (a que está no nome do caminho) ajusta o formato para
YYYYmmdd
- Colocá-lo em backticks faz com que seja uma substituição de comandos . Isso é o mesmo que você alcançaria digitando
$(date +%Y-%m-%d --date='1 day ago')
apenas que o último formulário (e mais recente) permite o aninhamento e é menos complicado em relação ao escape.
O efeito de Substituição de Comando em sua linha de comando é semelhante a atribuir
YESTERDAY1=$(date +%Y-%m-%d --date='1 day ago')
YESTERDAY2=$(date +%Y%m%d --date='1 day ago')
e depois reescrevendo a linha de comando assim
grep $YESTERDAY1 /path/to/file/FILE_PREFIX_$YESTERDAY2.dsv | grep -v 'ERROR' | cut -d "|" -f 2 | sed 's/^0/27/'
As partes individuais encadeadas por tubos
-
grep $YESTERDAY1 /path/to/file/FILE_PREFIX_$YESTERDAY2.dsv
greps para o valor da data de ontem no arquivo /path/to/file/FILE_PREFIX_$YESTERDAY2.dsv
e sai para stdout
(consulte Standard Streams )
-
grep -v 'ERROR'
greps para tudo outro que linhas contendo ERROR
. Ele faz isso na entrada de stdin
e também grava em stdout
.
-
cut -d "|" -f 2
assume que a linha de entrada (de stdin
) é delimitada por caracteres de canal ( -d "|"
, observe como o caractere de canal está em uma string aqui!) e escolhe o segundo campo ( -f 2
) e grava isso em stdout
.
-
sed 's/^0/27/'
substitui ( s/.../.../
) todas as strings de stdin
(lembre-se, segundo campo da entrada original) iniciando ( ^
) com 0 por 27 e grava-as em stdout
.
Tubulação
Agora, os caracteres de canal que aparecem fora de uma string, ou seja, todos, exceto o único em cut -d "|" -f 2
encadearam o stdout
do comando anterior para stdin
do comando a seguir.
Dessa forma, a saída do primeiro grep
que lê o arquivo, vai para o segundo grep
, o qual
Isso segue o princípio de filosofia do Unix "Faça uma coisa e faça bem" .
Colocando tudo junto
Na minha explicação, usei a variável YESTERDAY1
e YESTERDAY2
introduzida na seção Substituição de Comando. Agora você deve ser capaz de entender isso.
Uma coisa, no entanto. Eu duvido que isso aconteça, mas em um sistema muito lento em torno da meia-noite, o tempo entre a execução dessas duas substituições de comandos pode ser grande o suficiente para gerar valores diferentes para o nome do arquivo e o valor para o qual grep
.
A propósito
Se você quer ser realmente sofisticado e evitar o problema de que o valor de ontem poderia ser diferente, você pode usar Expansão de Parâmetro ( ${parameter/pattern/string}
) como tal. Primeiro, coloque a data em uma variável por meio de Substituição de comando :
YESTERDAY=$(date +%Y-%m-%d --date='1 day ago')
e, em seguida, use a Expansão do Parâmetro para remover os traços de uma vez da instância da variável da seguinte forma:
grep $YESTERDAY /path/to/file/FILE_PREFIX_${YESTERDAY//-}.dsv | grep -v 'ERROR' | cut -d "|" -f 2 | sed 's/^0/27/'
Dessa forma, você recupera o valor de data apenas uma vez e evita a chance (ainda que pequena) de obter datas diferentes.
Sugestão de leitura