Dado file
:
2018-03-22 foo/bar/baz
2020-09-30 Lorem/ipsum/dolor
2021-10-01 yadda/yadda/yadda
2022-03-14 blah/blah/blah
(os arquivos reais contêm milhares dessas linhas)
Como obter a corda 2018-03-22_2022-03-14
? Esta é a concatenação do campo 1 do registro 1, seguido por um sublinhado e, em seguida, o campo 1 do último registro.
Eu cheguei a isso:
$ awk 'BEGIN{ORS="_"}NR==1{print $1} END{print $1}' file | sed 's/_$//'
2018-03-22_2022-03-14
Funciona, mas parece que deve haver uma maneira não complicada de obter o mesmo resultado usando only awk
, ou talvez apenas sed
, sem pipes ou subshells. Existe de fato tal maneira?
A
sed
versão -somente:s/ .*//
para remover tudo após o espaço em branco, mantendo apenas a data1h
copia a data da linha1
nohold
espaço$!d
d
exclui todas as linhas exceto a últimaH
espaço antigo com nossa primeira data e copiamos ambas no espaço padrão comg
y/\n/_/
(E sim, é um pouco mais curto)
Para portabilidade, não faça
print $1
(ou use$anything
) naEND
seção, pois o valor de$0
,$1
, etc. naEND
seção é um comportamento indefinido por POSIX. Em alguns awks$1
daEND
seção será o valor do primeiro campo da última linha lida, em outros awks será null, e em outros awks ainda pode ser qualquer outra coisa.Usando qualquer awk em qualquer shell em cada caixa Unix:
ou para evitar imprimir um único
_
se o arquivo de entrada estiver vazio:O acima pressupõe que, se houver apenas 1 linha na entrada, você deseja o mesmo
$1
valor duplicado com um_
entre eles. Se não for isso que você deseja, atualize sua pergunta para esclarecer seus requisitos para esse caso.Uma maneira que é totalmente
awk
(embora não estritamente compatível com POSIX como @EdMorton aponta devido à referência de campo naEND
seção) é definir uma variável para o valor do campo 1 do registro 1 e, no final, imprimir essa variável com_
e campo 1 do último registro:nota: eu não tinha planejado que isso fosse uma pergunta do tipo "Q&A", mas o SE estava no modo somente leitura quando tentei enviar o Q , e nesse meio tempo finalmente descobri um A . Ainda gostaria de ver outras respostas, especialmente se forem mais curtas na linha de comando.
Use
printf
para controlar a saída:Eu sugiro que você use
head
etail
para arquivos de entrada grandes porqueawk
esed
são lentos para processar arquivos grandes.Isso é mais longo que o seu comando, mas tem o potencial de ser mais rápido se o arquivo for grande:
Se o arquivo for realmente delimitado por tabulação, você pode deixar de fora a extensão
-d' '
. Se o arquivo pode começar com-
, ou os$1
valores podem conter barras invertidas,pode ser mais seguro.
resultado