Localizando a posição de substring na string

2

Olhando para extrair a posição do terceiro campo, digitado pelo usuário, do arquivo "schemas.txt"

schemas="schemas.txt"
for i in ${schemas[@]};
do
    awk '{for(i=1;i<=NF;i++)if($i=="$3")print i}'
done 

Alguma idéia de por que estou preso em um loop infinito aqui?

EDIT: Adicionado um exemplo abaixo.

No schemas.txt, a segunda linha é "Ocupação de raça de idade de peso de pessoas"

Supondo que o usuário insira "age" como o terceiro parâmetro, gostaria que a linha fosse analisada e "4" a ser retornada, pois é a quarta palavra da string.

    
por Conman 24.10.2018 / 00:01

1 resposta

2

Se eu tiver acertado sua intenção, não acho que você precise do loop de shell. Em vez disso, forneça ao awk o (s) nome (s) do (s) arquivo (s) para ler na linha de comando. Podemos passar a palavra-chave para procurar com -v , ela define uma variável awk na linha de comando.

Assim, para cada linha que contenha "age", isso imprimiria o (s) número (s) de campo onde aparece:

$ cat schemas.txt
People height weight age race occupation
age is first on this line
$ keyword=age
$ awk -vk="$keyword" '{ for (i = 1 ; i <= NF ; i++) if($i == k) print i }' schemas.txt 
4
1

É claro que a palavra-chave fixa é apenas um exemplo, você pode usar awk -vk="$3" e pular a variável extra.

Em geral, parece que pode ser útil imprimir os números de linha também, você pode usar print NR, i para fazer isso.

Aqui,

schemas="schemas.txt"
for i in ${schemas[@]};
do
    awk '{for(i=1;i<=NF;i++)if($i=="$3")print i}'
done 

schemas contém apenas schemas.txt , de modo que a variável i do shell é definida no loop. No entanto, ele não é utilizado no loop, então o loop não faz muito. O i no script awk é independente do shell i .

awk parece travar aqui, já que por padrão ele lê stdin. Além disso, "$3" não é expandido pelo shell dentro das aspas simples, então o awk procuraria por um campo contendo literalmente $3 .

O loop faria mais sentido com vários arquivos:

files=(file1.txt file2.txt)
for file in "${files[@]}"; do
    awk '{...}' "$file"
done

mas mesmo assim você pode passar todos os arquivos para o awk de uma só vez:

awk '{...}' "${files[@]}"
    
por 24.10.2018 / 00:58

Tags