Por exemplo, eu tenho o documento de texto:
"Hello, I am the janitor and I have a headache The rabbit jumped over the red brick wall"
Eu quero contar o número de campos nos quais a substring “he” ocorre. Não quero contar o número de “ele” no arquivo, apenas o número de campos.
Então, para o meu exemplo, ele deve imprimir algo assim:
Number of fields that contain "he" in record #1: 3 Number of fields that contain "he" in record #2: 2
Deve ser um script awk.
Comentários
- O que você tentou até agora?
- Eu tentei o seguinte script: " {print " Número de campos no registro # " NR " contendo ' ele ': " índice ($ 0, " ele ")} e não ' não funciona. Eu também tentei gsub, mas gsub conta todas as ocorrências de ' ele ', não apenas os campos nos quais ' ele ' foi encontrado.
- Você precisa iterar nos campos. Isso deve ajudá-lo.
- Você abandonou unix.stackexchange.com/questions / 550529 / … ?
- @JohnMike também, coloque suas tentativas & seus resultados em sua pergunta , onde não ' ser esquecido.
Resposta
Os campos são numerados começando em 1
e NF
contém o número deles. Portanto, podemos iterar sobre eles com for (i = 1; i <= NF; i++) { ... }
, com $i
dentro do loop referindo-se ao campo em questão. (i
é na verdade apenas o número do campo, precisamos do operador $
para obter o conteúdo real do campo.)
E para descobrir se um valor contém uma substring específica, usar uma regex é mais fácil. s ~ /foo/
veria se a variável s
corresponde à string foo
em qualquer lugar, ou seja, se contém como uma substring. Agora, você também pode querer combinar uma letra maiúscula, caso em que, por exemplo, [Ff]
funcionaria no lugar de f
. O grupo de colchetes [...]
corresponde a qualquer um dos caracteres dentro.
É claro que você também precisará de um contador, mas isso é fácil, basta inicializar uma variável para zero antes do loop (por exemplo, count=0
) e incrementar se houver “uma correspondência (count += 1
).
~ ~
Então, basicamente, um script awk para executar algum código para cada linha / registro de um arquivo é apenas
awk "{ some code }" < filename.txt
Dentro do bloco de código, o for
loop se encaixa e também leva um bloco entre colchetes { .. }
.
awk "{ for ( ... ) { some code } }`
E um if
funciona de maneira semelhante,
if (condition) { some code... }
(Eles realmente parecem apenas como for
e if
em C.)
E você pode usar ponto-e-vírgula para separar instruções, então
awk "{ what to do before the loop; for ( ... ) { some code }; what to do after }`
Comentários
- como seria um arquivo de script completo? Eu m com perda total. Nosso professor não ' não falou sobre essas coisas.
- @JohnMike, bem, que ' é exatamente o que há , Eu realmente odeio dar respostas completas para o dever de casa. Isso deve ser sobre todas as peças, no entanto, se você tiver tempo para tentar construir algo a partir delas.
- Eu não ' t, e normalmente não ' não pediria respostas completas, mas estou preocupado em obter um A nesta aula. Eu ' sou um aluno A direto e geralmente não tenho problemas com minhas aulas de computação científica, mas esse professor é famoso por esperar conhecimento fora da classe. Eu ' nunca usei unix / linux antes e estou realmente tendo dificuldades aqui. O dever de casa consiste em 20 problemas, e esses 3, mais 2 em outra postagem que fiz, são os únicos que eu ' não consigo resolver. Estou ficando sem tempo, ' é amanhã.
- @JohnMike, tente se você consegue juntar algumas peças?SE é péssimo para a depuração interativa, mas você pode editar seu Q para adicionar um script se avançar um ou dois passos, e então podemos ver o que ' é o stopper
- @JohnMike Considerando (a) a maneira mostrada aqui para iterar nos campos de cada registro usando o loop for, (b)
gsub
que você tentou sua postagem abandonada pode aceitar uma meta para executar, ou seja,gsub("he","",$i)
(c) você tem um histórico de comp sci básico (d) pode usar ferramentas online como tutorialspoint.com/execute_bash_online.php para fazer sua lição de casa mesmo que você não tenha o linux em seu pc, então não há nenhuma desculpa forte para não tentar resolver sua lição de casa com a ajuda dada aqui. Faça pelo menos uma tentativa e a ajuda chegará.
Resposta
Feito pelo script awk abaixo
awk -v i="he" "{print "Number of fields that contain" " " i " " gsub("he",$0) " " "in record " NR}" file
saída
Number of fields that contain he 3 in record 1 Number of fields that contain he 2 in record 2