Obter última coluna de string sem AWK

1

Eu queria saber se eu poderia usar sed ou grep (mas não -P flag) para dar a mesma funcionalidade que awk '{print $6}' .

Estou fazendo um script para iOS, mas não quero ter que instalar comandos de terceiros (como awk ).

  • O grep no iOS também não suporta o -P , portanto, não perl-regexp .
  • cut é um comando de terceiros no iOS (portanto, não cut )
por Jacob Collins 05.02.2018 / 08:50

5 respostas

6

Se você tem uma string em uma variável em um script e você gostaria de extrair o último campo (como você diz no título da pergunta), então você pode fazer

field=${string##* }

Isso pressupõe que a string em $string seja separada por espaços (altere o espaço na substituição de variável acima para qualquer delimitador que estiver usando). A substituição da variável ${variable##pattern} remove a string de prefixo mais longa de $variable que corresponde ao dado pattern .

Com sed em um arquivo, o seguinte extrairia o último campo separado por espaço em branco de cada linha:

sed 's/^.*[[:space:]]//' data.in

Ele faz isso excluindo tudo até e incluindo o último caractere de espaço em branco em cada linha. Altere [[:space:]] para uma expressão regular que corresponda ao delimitador antes da última coluna se seus dados não usarem tabulações ou espaços como delimitadores.

    
por 05.02.2018 / 08:55
3

Para obter a última coluna delimitada em branco com uma% de sed compatível com POSIX (o equivalente a awk '{print $NF}' ) e supondo que a entrada seja um texto válido:

sed 's/[[:blank:]]*$//; # remove trailing blanks
     s/.*[[:blank:]]//; # remove every thing up to the last blank
    ' < file

Observe que a maioria das implementações de awk separa os campos em espaços em branco (espaçamento horizontal), mas alguns (busybox awk ) separam em todos os espaços ( [[:space:]] ) e alguns somente nos espaços em branco ASCII (espaço e tabulação) independentemente da localidade. Nos arquivos provenientes de sistemas operacionais da Microsoft, você pode substituir [[:blank:]] por [[:space:]] , de modo que considere o caractere CR como espaçamento e descarte-o.

Para obter o sexto campo (equivalente a awk '{print $6}' ):

s='[[:blank:]]' S='[^[:blank:]]'
sed "s/^$s*\($S\{1,\}$s\{1,\}\)\{5\}\($S\{1,\}\).*//; t
     s/.*//; # flush the line if does not have 6 fields"

Você também pode usar uma abordagem como:

sed 's/[^[:blank:]]\{1,\}/\
&\
/6; s/.*\n\(.*\)\n.*//;t
s/.*//'
    
por 05.02.2018 / 10:26
2

Com grep , assumindo que a opção -o esteja disponível (também, passando pelo título que a última coluna é necessária, não apenas coluna específica)

$ echo 'foo bar 123' | grep -o '[^ ]*$'
123
$ echo 'foo;bar;123' | grep -o '[^;]*$'
123
    
por 05.02.2018 / 09:25
0

Alguém poderia fazer algo assim:

$ var="This is a string"; printf "%s\n" $var | { while read -r line; do  last="$line"; done; printf "%s\n" "$last"; }
string

Isso tira proveito da divisão de palavras e da capacidade de printf de manter os argumentos de montagem para formatar a string, mesmo se o número deles não corresponder. Isso nos permite transformar cada palavra ou campo de string em linhas separadas. Isso é acoplado com o loop while read -r variable; do...done padrão para lendo stdin stream linha por linha, onde acabamos de obter a última linha, também conhecido como último campo.

Isso é um monte de acrobacias, mas é uma abordagem shell que não depende de ferramentas externas. No entanto, para o realmente modo portátil e adequado apenas para shell, a resposta de Kusalananda ainda é melhor.

    
por 05.02.2018 / 09:49
0

Eu testei para o caso abaixo com delimitador de espaço para imprimir a última coluna usando o comando sed e funcionou bem

input.txt

praveen ajay abhi

Método1

echo "praveen ajay abhi"| sed -r "s/.* //g"

saída

abhi

    
por 05.02.2018 / 11:16

Tags