Como eu pude duas vezes em uma passagem?

7

Existe uma maneira de evitar fazer grep duas vezes no arquivo e apenas preencher o variáveis em uma passagem? O arquivo é pequeno por isso não é tão grande coisa que eu só queria saber se eu poderia fazer isso de uma só vez

FIRST_NAME=$(grep "$customer_id" customer-info|cut -f5 -d,)
LAST_NAME=$(grep "$customer_id" customer-info|cut -f6 -d,)
    
por Jim 27.03.2018 / 10:02

4 respostas

13

Você pode fazer o grep uma vez e dividir duas vezes usando a substituição de string do shell:

NAME=$(grep "$customer_id" customer-info | cut -f5,6 -d,)
FIRST_NAME=${NAME%,*}
LAST_NAME=${NAME#*,}

Ou, com o bash, usando a substituição do processo:

IFS=, read FIRST_NAME LAST_NAME < <(grep "$customer_id" customer-info | cut -f5,6 -d,)

read dividirá a entrada em IFS e atribuirá o primeiro valor a FIRST_NAME e o restante a LAST_NAME . Usando o processo de substituição e redirecionamento < <(...) permite que você passe a saída de grep ... | cut ... para read sem usar um subshell.

    
por 27.03.2018 / 10:10
4

O mais simples seria colocar o registro inteiro em uma variável e, em seguida, usar cut sobre isso.

RECORD=$(grep "$customer_id" customer-info)
FIRST_NAME=$(echo "$RECORD"|cut -f5 -d,)
LAST_NAME=$(echo "$RECORD"|cut -f6 -d,)

Também, pessoalmente, recomendo usar uma expressão regular mais específica. Se os seus IDs de cliente estiverem sempre no início da linha, você pode escrever grep '^'"$customer_id" em vez de grep "$customer_id" para exigir que a correspondência esteja no início da linha. Caso contrário, você pode pegar registros em que o texto que corresponde ao ID do cliente aparece em outro lugar no registro.

    
por 27.03.2018 / 12:48
4

Você pode usar awk em combinação com o bash read :

read -r FIRST_NAME LAST_NAME <<< $(awk -F, -v cid="$customer_id" '$0~cid{print $5,$6}' customer-info)

-F diz ao awk para usar a vírgula como delimitador de campo

-v define a variável awk cid como a variável do shell $customer_id

Se a linha corresponder ao $customer_id , o awk imprimirá os campos 5 e 6 e estes serão atribuídos às variáveis FIRST_NAME e LAST_NAME .

Se o primeiro nome ($ 5) contiver espaço (exemplo: a, b, c, d, Sarah Jane e Smith), adicione -v OFS=, para ter awk vírgula de saída entre campos e prefixo read com IFS=, tê-lo dividido em vírgula.

Além disso, awk pode pesquisar em apenas um campo específico como '$3~cid{print..}' - e pode corresponder a esse campo inteiro por '$3~"^"cid"$"{print...}' se isso for importante para seus IDs.

    
por 27.03.2018 / 10:21
2

Arquivo pequeno, arquivo grande. Um hábito que tenho é sempre eliminar o disco IO, tanto quanto posso. Uma maneira de fazer isso é enviar o arquivo para uma matriz. É claro que isso requer que o env $ IFS seja configurado adequadamente para o arquivo, mas elimina o IO.

data=( $(cat customer-info) )

Então você pode escolher isso ...

FIRST_NAME=$(echo "${data[@]}" | tr ' ' '\n' | grep "$customer_id" | cut -f5 -d,)

Outro método pode ser atribuir apenas os dois bits desejados a um array, assim ...

data=( $(grep "${customer_id}" customer-info | cut -d, -f5,6) )

    
por 27.03.2018 / 10:14