
Preciso de ajuda para descobrir como usar o comando sed para mostrar apenas a primeira e a última coluna em um arquivo de texto. Aqui está o que tenho até agora para a coluna 1:
cat logfile | sed 's/\|/ /'|awk '{print $1}'
Minha fraca tentativa de exibir também a última coluna foi:
cat logfile | sed 's/\|/ /'|awk '{print $1}{print $8}'
No entanto, isso pega a primeira coluna e a última coluna e as mescla em uma lista. Existe uma maneira de imprimir a primeira coluna e as últimas colunas claramente com os comandos sed e awk?
Exemplo de entrada:
foo|dog|cat|mouse|lion|ox|tiger|bar
Responder1
Quase lá. Basta colocar as duas referências de coluna próximas uma da outra.
cat logfile | sed 's/|/ /' | awk '{print $1, $8}'
Observe também que você não precisa cat
aqui.
sed 's/|/ /' logfile | awk '{print $1, $8}'
Observe também que você pode dizer awk
que os separadores de coluna são |
, em vez de espaços em branco, portanto você não precisa sed
de nenhum deles.
awk -F '|' '{print $1, $8}' logfile
ConformesugestõesporCalebe, se você quiser uma solução que ainda produza o último campo, mesmo que não haja exatamente oito, você pode usar $NF
.
awk -F '|' '{print $1, $NF}' logfile
Além disso, se desejar que a saída retenha os |
separadores, em vez de usar um espaço, você poderá especificar os separadores de campo de saída. Infelizmente, é um pouco mais desajeitado do que apenas usar a -F
bandeira, mas aqui estão três abordagens.
Você pode atribuir os separadores de campos de entrada e saída por
awk
si só, no bloco BEGIN.awk 'BEGIN {FS = OFS = "|"} {print $1, $8}' logfile
Você pode atribuir essas variáveis ao chamar
awk
a partir da linha de comando, por meio do-v
sinalizador.awk -v 'FS=|' -v 'OFS=|' '{print $1, $8}' logfile
ou simplesmente:
awk -F '|' '{print $1 "|" $8}' logfile
Responder2
Você está usando awk
de qualquer maneira:
awk '{ print $1, $NF }' file
Responder3
Basta substituir do primeiro ao último |
por um |
(ou espaço se preferir):
sed 's/|.*|/|/'
Observe que embora não haja sed
implementação onde |
é especial (desde queestendidoexpressões regulares não são habilitadas em -E
ou -r
em algumas implementações), \|
em si é especial em algumas como GNU sed
. Então você deverianãoescape |
se você pretende que corresponda ao |
personagem.
Se substituir por espaço e se a entrada já puder conter linhas com apenas one |
, você terá que tratar isso especialmente, pois |.*|
não corresponderá a elas. Isso poderia ser:
sed 's/|\(.*|\)\{0,1\}/ /'
(isto é, tornar a .*|
parte opcional) Ou:
sed 's/|.*|/ /;s/|/ /'
ou:
sed 's/\([^|]*\).*|/\1 /'
Se você quiser o primeiro e o oitavo campos, independentemente do número de campos na entrada, basta:
cut -d'|' -f1,8
(todos eles funcionariam com qualquer utilitário compatível com POSIX assumindo que a entrada forma texto válido (em particular, aqueles sed
geralmente não funcionarão se a entrada tiver bytes ou sequências de bytes que não formam caracteres válidos no local atual, como por exemplo printf 'unix|St\351phane|Chazelas\n' | sed 's/|.*|/|/'
em uma localidade UTF-8)).
Responder4
Parece que você está tentando obter o primeiro e o último campos de texto delimitados por |
.
Presumi que seu arquivo de log contém o texto abaixo,
foo|dog|cat|mouse|lion|ox|tiger|bar
bar|dog|cat|mouse|lion|ox|tiger|foo
E você quer uma saída como,
foo bar
bar foo
Se sim, então aqui vem o comando para o seu
Através do GNU sed,
sed -r 's~^([^|]*).*\|(.*)$~\1 \2~' file
Exemplo:
$ echo 'foo|dog|cat|mouse|lion|ox|tiger|bar' | sed -r 's~^([^|]*).*\|(.*)$~\1 \2~'
foo bar