Filtrando o Dataset com o AWK baseado na lista

1

Eu quero obter linhas filtradas do dataframe com base na condição, se elas estiverem presentes na lista. Até agora eu tentei essa coisa. Mas estou obtendo um resultado inesperado. Os dados estão sendo replicados e não consigo entender

#!/bin/bash
arr_country=(AL AD AM AT BY BE BA BG CH)
for element in "${arr_country[@]}"
do
awk -F '\t' '{if($1==$element){print}}'   abc.txt >>xyz.txt
done
echo
echo "Data Transferred"

O conjunto de dados de amostra contém informações sobre diferentes países com a primeira coluna representando o nome do país. Eu quero subconjunto do conjunto de dados com base na matriz fornecida.

    
por Anushree Mahajan 08.10.2018 / 11:35

1 resposta

1

element não é uma variável awk .

Para importar o valor de uma variável shell para um script awk , você pode usar

awk -v variable="$value" '{ script goes here }'

No exemplo acima, a variável chamada variable obteria o valor da variável shell chamada value . Você usaria variable no script awk sem prefixá-lo com $ .

Observe que, se você prefixar uma variável com $ em awk , ela assumirá que o valor da variável é um inteiro positivo e se refere a um campo específico no registro de entrada atual. A expressão $element forneceria, por exemplo, o valor do campo element (assim como $1 fornece o valor do primeiro campo e $NF fornece o valor do último campo, em que NF é a variável interna que indica o número de campos no registro atual).

Se element não estiver definido no código awk , $element será, portanto, expandido para $0 , que é a linha completa. Seu código imprimiria a linha inteira se seu primeiro campo delimitado por tabulação fosse a única coisa na linha.

Seu script awk também pode ser reduzido para

awk -F '\t' -v e="$element" '$1 == e'

Ou você pode substituir a coisa toda por

arr_country=(AL AD AM AT BY BE BA BG CH)

( IFS='|'; grep -E "^(${arr_country[*]})\>" ) <abc.txt >xyz.txt

ou

grep -E '^(AL|AD|AM|AT|BY|BE|BA|BG|CH)\>' <abc.txt >xyz.txt

A substituição do parâmetro ${arr_country[*]} será expandida para uma única string, consistindo nos valores da matriz, delimitados pelo primeiro caractere de $IFS . Isso cria uma expressão regular idêntica à segunda grep mostrada acima. \> corresponderá ao espaço de largura zero no final de uma palavra (para que ^AA\> corresponda a AA no início de uma linha, mas não AAA ).

A única diferença é que o resultado pode ser ordenado diferentemente em comparação com a solução de loop de shell com awk .

Uma abordagem diferente para eliminar o loop do shell (assumindo o valor padrão de $IFS ):

arr_country=(AL AD AM AT BY BE BA BG CH)

awk -v c="${arr_country[*]}" -F '\t' '
    BEGIN { n=split(c,a," "); for (i=1;i<=n;++i) country[a[i]] }
    $1 in country' <abc.txt >xyz.txt

Aqui, fornecemos os elementos de arr_country como uma string delimitada por espaço ao código awk na variável c . Antes de começar a ler a entrada, a string c é dividida em partes e cada parte é transformada em uma chave em uma matriz associativa country . Se o primeiro campo for uma chave nessa matriz, a linha será impressa.

    
por 08.10.2018 / 11:39