
Aqui está o código de um script onde devo verificar se o nome do arquivo é 'pretempsc.cfg' e imprimir seu conteúdo como está. . Para qualquer outro arquivo, devo modificar apenas as linhas que começam com 'abc disable ...' para 'no abc ...'.
#!/bin/sh
IN_FILE=$1
OUT_FILE=$2
WhatFileIsIt() {
awk -v filename=$IN_FILE '
BEGIN {
scnode = 0;
if (filename == "pretempsc.cfg") {
scnode = 1; }
}
{
if (!scnode) {
/^abc disable/ {
print "no abc "$4"";
next;
}
print;}
}
else {print}
}
'
}
cat $IN_FILE | WhatFileIsIt | cat > $OUT_FILE
Ao executar este script, recebo o seguinte erro:
awk: cmd. line:9: /^abc disable/ {
awk: cmd. line:9: ^ syntax error
awk: cmd. line:16: else {print}
awk: cmd. line:16: ^ syntax error
Pelo que pude observar, suspeito que estou errado no uso de if e condição-ação dentro do bloco de ação, mas não consigo descobrir exatamente o que está errado.
Para observar: DEVO usar awk dentro do script de shell, e há muitas outras funções semelhantes a WhatFileIsIt fazendo seu próprio processamento no IN_FILE.
Responder1
Sim, você precisa alterar essa correspondência de padrão para uma if
instrução completa:
if (/^abc disable/) {
print "no abc "$4"";
next;
}
( /pattern/
é uma abreviação de $0 ~ /pattern/
, onde $0
contém toda a linha de entrada.)
Observe que print
lá imprime apenas a quarta coluna da entrada depois de no abc
, então abc disable foo bar doo
se transforma em apenas no abc bar
. Não tenho certeza se era isso que você queria.
Enquanto estamos nisso, algumas outras coisas vêm à mente... Sinta-se à vontade para ignorar qualquer uma dessas coisas, se elas forem muito óbvias ou entrarem em conflito com o resto do seu roteiro. (E espero não ter cometido muitos erros.)
Acho que há uma chave extra direita no final do print
, e parece que o recuo da condição mais profunda está um pouco errado, então reescreva um pouco:
{
if (!scnode) {
if (/^abc disable/) {
print "no abc " $4;
next;
}
print;
} else {
print;
}
}
Mas a partir daqui, parece que a única vez que algo especial é feito é quando ambos !scnode
são verdadeiros e /^abc disable/
correspondem; em todos os outros casos, há apenas o print
. Portanto, poderíamos combinar as condições com &&
(é claro que a separação entre diferentes tipos de arquivos não é mais tão clara):
{
if (!scnode && /^abc disable/) {
print "no abc "$4"";
next;
} else {
print;
}
}
Como existe um next
que encurta a execução, o final print
pode ficar sem a else
cláusula e, de fato, como todo o bloco de código é apenas um if
, poderíamos deixar a condição cair no nível principal e seguir com uma ação padrão incondicional de impressão.
!scnode && /^abc disable/ {
print "no abc "$4"";
next;
}
1;
(É claro que isso pode parecer um pouco condensado agora.)
Além disso, no shell script, você não precisa incomodar os gatos, é melhor deixá-los dormindo e usar apenas o shell para redirecionamento. (E cite as variáveis do shell.)
WhatFileIsIt < "$IN_FILE" > "$OUT_FILE"
O nome dessa função é um pouco confuso, ela realmente não responde a nenhuma pergunta "o quê", mas processa um arquivo. Talvez algo como ProcessFile
?
E bem, falando em funções, essa função usa a variável IN_FILE
, que não é local para ela. Pode ser confuso se houver necessidade de executar uma função para dois arquivos diferentes. Assim como o próprio script de shell, a função também pode receber parâmetros, chamar MyFunction foo
e fazer $1
conter foo
dentro da função.
Então talvez eu fizesse algo como
ProcessFile() {
awk < "$1" -v filename="$1" '
[...]
(Não importa se você coloca o redirecionamento de entrada no meio ou no final da linha de comando do awk.)
Usar com:
ProcessFile "$IN_FILE" > "$OUT_FILE"