podemos imprimir a última palavra de cada linha no linux usando o comando sed?

8

suponha que, se houver um arquivo que contenha as seguintes linhas, se elas forem

12345 567 7878 66

   er3   t45t y6y46y 


 4y6 y656y y5y

   46y6 65y7 y66uyuy

 yy46y6y

A saída tem que se parecer com:

66

y6y46y

y5y

y66uyuyy

y46y6y

Eu tentei o comando sed 's/.* //g' filename e vários outros comandos sed , mas não está funcionando.

Posso saber qual é o comando sed exato?

    
por Rajeev Nukala 27.01.2015 / 21:40

8 respostas

8

awk '{print $NF}'
sed 's/[[:blank:]]*$//;s/.*[[:blank:]]//'

Isso ainda imprime uma linha vazia para cada linha em branco. Para evitar isso:

awk 'NF{print $NF}'
sed 's/[[:blank:]]*$//;s/.*[[:blank:]]//;/./!d'
    
por 27.01.2015 / 21:48
6

A awk variable $NF é o último campo de cada registro ; você pode usá-lo para imprimir apenas os últimos campos do seu arquivo da seguinte forma:

awk '{print $NF}' file
    
por 27.01.2015 / 21:48
4

Você pode tentar:

  • sed 's/.* //'
  • awk '{print $NF}'
por 27.01.2015 / 21:48
3

Você está quase lá. Basta especificar a última palavra:

sed 's/^.* \([^ ][^ ]*\)//g'

O que faz:

  1. '^. *' exclui tudo no início da linha e em quaisquer espaços.
  2. '\ (...) \' corresponde a um padrão e retorna como \ 1.
  3. '[^]' corresponde a qualquer coisa sem espaço.

(Editado para adicionar uma solução melhor. Obrigado Hildred!)

    
por 28.01.2015 / 01:20
2

Você pode usar um padrão adequado de grep em vez de sed , por exemplo:

grep -o "[a-Z0-9]*$"

Neste exemplo, o [...] contém intervalos de caracteres considerados apropriados para uma "palavra" (alfanuméricos, neste caso, outros símbolos podem ser adicionados, alguns dos quais devem ser escapados).

    
por 27.01.2015 / 21:49
0

Se você qualifica palavra para significar qualquer sequência de 1 ou mais caracteres não-brancos então a resposta é definitivamente sim, e é muito simples também. Isso ocorre porque [[:blank:]]* e [^[:blank:]]* são complementos booleanos e - desde que todos os caracteres em uma cadeia estejam completos - [[:blank:]]* U [^[:blank:]]* pode descrever qualquer sequência possível da mesma maneira que .* .

Se existir um caractere incompleto ou uma seqüência de byte inválida dentro de uma string, não é possível descrevê-lo com sucesso - como às vezes pode ocorrer quando se interpreta uma string na codificação incorreta. Para garantir um caractere completo por byte em qualquer string, a localidade C pode ser forçada como:

LC_ALL=C sed ...

... o que evitaria quaisquer problemas que descrevessem a string da cabeça à cauda com um padrão all-inclusive, como .* ou ([ ]*[^ ]*)*

Um padrão totalmente complementar pode se repetir quantas vezes for necessário, da esquerda para a direita, o comprimento de qualquer corda para pousar na última ocorrência possível, sem qualquer quebra no padrão. Isto é, definitivamente, linguagem regular.

BRE:

sed 's/\(\([^[:blank:]]*\)[[:blank:]]*\)*//'

ERE:

sed -E 's/(([^[:blank:]]*)[[:blank:]]*)*//'

Ambas as versões ainda imprimirão linhas em branco, e isso ocorre porque a estrela Kleene * corresponde a zero ou mais ocorrências de um padrão. Primeiramente, ele corresponde a zero ou mais caracteres não em branco, depois a zero ou mais caracteres em branco e, em seguida, a zero ou mais ocorrências das correspondências agrupadas até que corresponda à string em sua totalidade.

Tendo combinado tudo isso, a mágica acontece na substituição - as referências retornadas pelos grupos e são as últimas ocorrências de cada uma. Assim, quando a substituição é feita, toda a string é substituída apenas pela última ocorrência em uma linha de zero ou mais caracteres não em branco - ou o subgrupo .

É claro que isso funciona para qualquer seqüência possível - até mesmo uma vazia - o que significa que os dois formulários imprimirão caracteres de nova linha para linhas que contenham apenas caracteres em branco ou nenhum. Para lidar com isso, há algumas coisas que você pode fazer, mas primeiro vamos tornar a classe de caracteres um pouco mais fácil de digitar:

b='[:blank:]'

Agora, para imprimir apenas se uma linha contiver um ou mais caracteres não em branco, você pode fazer:

BRE:

sed -n "s/\(\([^$b]*\)[$b]*\)*//;/./p"

ERE:

sed -En "/[^$b]/s/(([^$b]*)[$b]*)*//p"
    Caso de
  1. BRE - a substituição é sempre executada e apenas os espaços de padrão com pelo menos um caractere restante são impressos.
  2. ERE case - a substituição só é tentada em um espaço de padrão contendo pelo menos um caractere em branco.

Qualquer um dos formulários funcionará com um dos métodos, desde que a sintaxe esteja correta.

A chave -n desabilita a impressão automática do espaço padrão, e a% bandeira p aos comandos s/// ubstitution ou / address / imprime seus resultados somente se for bem-sucedida.

Essa mesma lógica pode ser aplicada para obter qualquer {num} th ocorrência, assim como:

BRE:

sed -n "s/\([$b]*\([^$b]\{1,\}\)\)\{num\}.*//p"

ERE:

sed -En "s/([$b]*([^$b]+)){num}.*//p"

... onde o num em ambos os regexps pode ser substituído por um número para imprimir somente a {num} th ocorrência especificada de uma seqüência de caracteres não em branco. Uma forma ligeiramente diferente é usada aqui para garantir que a contagem não seja distorcida para espaços iniciais em uma string.

Observe que a opção -E ERE para sed é suportada nas versões BSD e GNU, embora não seja ainda sintaxe padrão POSIX.

    
por 28.01.2015 / 04:15
-1

Sim. O seguinte comando sed primeiro remove todos os espaços em branco finais ( s/ *$// ) e, em seguida, tudo até e incluindo o último espaço em branco ( s/.* // ). Provavelmente vale a pena substituir o espaço em branco literal por [[:blank:]] para capturar guias e outros caracteres semelhantes a espaço.

$ echo "  aaa bbb cc   " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "  aaa bbb cc" | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "aaa bbb cc   " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "aaa bbb cc" | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "  cc  " | sed -e 's/ *$//' -e 's/.* //'
cc
$ echo "cc" | sed -e 's/ *$//' -e 's/.* //'
cc
    
por 28.01.2015 / 10:05
-1
cat file_name | rev | cut -f1 -d ' ' | rev
    
por 06.05.2016 / 13:51