2010-01-10 11 views
2

Je veux intégrer un script awk dans un script shell mais j'ai du mal à le faire car je ne sais pas où terminer une instruction avec un; et où pas.Écrire un script shell wrapper pour awk

Voici mon scénario

#!/bin/sh 

awk=' 

BEGIN {FS = ",?+" } 

# removes all backspaces preceded by any char except _ 
function format() { 
    gsub("[^_]\b", "") 
} 

function getOptions() { 
    getline 
    format() 

    print 
} 

{ 
    format() 

    if ($0 ~ /^SYNOPSIS$/ { 
     getOptions() 
     next    
    } 

    if ($0 /^[ \t]+--?[A-Za-z0-9]+/) { 
     print $0 
    } 
} 

END { print "\n" }' 

path='/usr/share/man/man1' 
list=$(ls $path) 

for item in $list 
do 
    echo "Command: $item" 
    zcat $path$item | nroff -man | awk "$awk" 
done > opts 

J'utilise nawk par la voie.

Merci à l'avance

+0

Désolé de causer beaucoup de confusion ici ^^ ... tout d'abord, j'ai posté la mauvaise version du script, qui est corrigée maintenant ... en second lieu, le script fonctionne maintenant: -) ... le raison était que j'ai oublié de mettre $ awk entre guillemets, cela m'a toujours donné une erreur de syntaxe sur la première ligne du script ... – helpermethod

+0

Merci à tous pour vos réponses, ils ont fourni une grande perspicacité ^^ – helpermethod

Répondre

5

Il y a plusieurs choses mauvaises, pour autant que je peux voir:

  1. Vous ne fermez pas la chaîne multi-ligne étant affectée à $awk. Vous avez besoin d'un devis unique sur la ligne après END { ... }
  2. Vous ne semblez pas réellement utiliser$awk partout. Peut-être que vous vouliez dire sur l'invocation de awk à l'intérieur de la boucle do.
  3. Une fois que vous avez corrigé ces problèmes, awk est généralement assez indulgent sur les points-virgules, mais les problèmes à cet égard n'ont rien à voir avec l'utilisation dans un script shell.
1

Je ne suis pas vraiment sûr de ce que vous vouliez dire, mais si je vous comprends bien, votre showOpts.awk est que le code awk au début de votre script, vous pouvez le faire

path='/usr/share/man/man1' 
list=$(ls $path) 

for item in $list 
do 
    echo "Command: $item" 
    zcat $path$item | nroff -man | nawk ' BEGIN {FS = ",?+" } 
# removes all backspaces preceded by any char except _ 
function format() { 
    gsub("[^_]\b", "") 
} 

function getOptions() { 
    getline 
    format() 

    print 
} 

{ 
    format() 

    if ($0 ~ /^SYNOPSIS$/ { 
     getOptions() 
     next 
    } 

    if ($0 /^[ \t]+--?[A-Za-z0-9]+/) { 
     print $0 
    } 
} 

END { print "\n" } ' 
done >> opts 

et vous devriez probablement utiliser >> au lieu de>.

+3

Je dirais que l'intégration du programme littéral awk dans la boucle rend le script shell très difficile à lire. L'assigner à une variable en premier (comme l'OP essayait de le faire) et ensuite en invoquant 'awk" $ awk "' est beaucoup plus lisible. –

+2

Étant donné que la redirection est en dehors de la boucle, il n'y a aucune raison pour que ce soit un append. –

3

Ces trois lignes:

path='/usr/share/man/man1' 

list=$(ls $path) 

for item in $list 

besoin d'être changé en:

path='/usr/share/man/man1' 

for item in $path/* 

en cas il y a des espaces dans les noms de fichiers et depuis ls ne sont pas destinés à être utilisés de cette façon.

+0

Après ce bon changement, '$ path $ item' devrait être simplement' $ item'. Et aussi, les expansions variables doivent être citées. Donc, "zcat" $ item "| nroff -man | awk "$ awk" ' –

+0

Vous avez raison, merci. –

Questions connexes