2009-06-28 11 views
1

J'écris un script shell, qui à un moment donné doit prendre un fichier, rechercher un mot particulier et supprimer le texte entier qui vient après ce mot (y compris le mot lui-même) - awk est le bon outil je suppose, mais je ne connais pas vraiment grand chose de la programmation.Comment supprimer une partie du fichier avec awk

Quelqu'un peut-il m'aider?

Répondre

8

Je suppose que 'awk' est un outil pour le travail, même si je pense que 'sed' est plus simple pour cette opération particulière. La spécification est un peu vague. La version simple est:

  • Trouvez la première ligne contenant un mot donné.
  • Supprimez cette ligne et toutes les lignes suivantes.

Pour cela, j'utiliser sed:

sed '/word/,$d' file 

La version plus complexe est:

  • Trouver la première ligne contenant un mot donné.
  • Supprimer le texte sur cette ligne à partir du mot.
  • Supprimez toutes les lignes de texte suivantes.

j'utiliser probablement encore sed:

sed -n '1,/word/{s/word.*//;p}' file 

Inverse la logique. Il n'imprime rien par défaut, mais pour les lignes 1 jusqu'à la première ligne contenant le mot, il fait un remplacement (qui ne fait rien jusqu'à la ligne contenant le mot), puis imprime.

Peut-il être fait dans 'awk'? Pas complètement trivial parce que 'awk' auto-splite les lignes d'entrée en mots, et parce que vous devez utiliser des fonctions pour faire des substitutions.

awk '/word/ { if (found == 0) { 
       # First line with word 
       sub("word.*", "") 
       print $0; 
       found = 1 
       } 
      } 
      { if (found == 0) print $0; }' file 

(Modifié: changement « supprimer » à « trouvé » depuis « supprimer » est un mot réservé dans « awk ».)

Dans tous ces exemples, la version tronquée du fichier d'entrée est écrit sur la sortie standard. Pour modifier le fichier in situ, vous devez soit utiliser Perl ou Python ou une langue similaire, soit capturer la sortie dans un fichier temporaire que vous copiez sur l'original une fois la commande terminée. (Si vous essayez vous traitez « fichier script » un fichier vide.)

Il existe différentes optimisations de sortie précoce qui pourraient être appliquées aux scripts sed et awk, tels que:

sed '/word/q' file 

Et, si vous Supposons l'utilisation des versions GNU de awk ou sed, il existe diverses extensions non standard qui peuvent aider à la modification in-situ du fichier.

+0

D'accord, probablement faire 1'd aussi dans encore,. – Stobor

+0

sed -e «/\ . */{S ///; q} fait la même chose, et précise que le mot une fois. (1 avait un commentaire précédent portage à faire la même chose, mais le match était mal ...), vous voulez probablement également spécifier \ pour éviter de se faire prendre sur les épées de quelqu'un. – Stobor

+0

@Stobor: Eh bien, bien sûr, nous entrons dans un territoire intéressant avec la définition des mots, ainsi que la définition de la version de la syntaxe regex « et » supports. La notation « \ » est excellent lorsqu'il est supporté; Traditionnellement, il est pas pris en charge, si 1 trouvent qu'il est pris en charge sur Solaris (un peu à ma grande surprise). –

1

Je suppose que votre entrée est quelque chose comme ceci:

Lorem ipsum dolor sit amet, consectetur adipiscing
velit.
relais ou Playstation, la télévision et la planification ne
fournisseur d'hébergement eu. Pour moi, personne ne
. réseaux Mécène.

et vous voulez que la sortie soit coupée au mot 'vel' comme ceci:

lorem ipsum carottes, de tomates de premier cycle
veut.
relais ou Playstation, la télévision

Dans ce cas, votre script awk serait:

cat lorem.txt | awk ' 
    /\<vel\>/ 
    { 
    print substr($0, 0, match($0, /\<vel\>/) - 1); 
    exit; 
    } 

    { print } 
' 

Le mot que vous voulez couper à des besoins de remplacer les deux occurrences du mot vel dans le script .

Vous pouvez en toute sécurité mettre le script sur une seule ligne, aussi.

+1

@Stobor utilisation inutile de chat, il est jamais une bonne idée. – Erik

+0

@Erik: 1'm ne va pas entrer dans l'argument sur le mot « jamais » ... Autant dire 1 d'accord que ce n'est pas utile ici. – Stobor

0

1'm ne sais pas comment le faire avec awk, mais vous pouvez le faire avec mais

sed -i~ -e 's/the-word-to-find.*$//' the-file 

Ceci effacera tout de the-word-to-find à la fin de la ligne, sur chaque ligne qui contient the-word-to-find . Si vous voulez supprimer le reste du fichier lors de la première occurrence de the-word-to-find, vous pouvez faire:

sed -i~ -e 's/\(the-word-to-find\).*$/\1/;/the-word-to-find/,$d' 
+0

Le second a fonctionné parfaitement - merci beaucoup :) –

0

Ce awk one-liner devrait faire l'affaire. {sous (/ mot */« »); } Imprimer pour chaque ligne, si la ligne contient un modèle qui commence par le mot (procédé par l'espace) et se dirige vers la fin de la ligne - remplacer le modèle par la chaîne vide - puis imprimer la ligne mise à jour.

[Figured la question pouvait lire de toute façon (texte tout sur cette ligne ou le texte entier dans le fichier). Si l'on voulait sauter le reste des fichiers on peut: {sauter = gsub (./Mot * /, « »); impression; si (sauter) exit}]

+0

Je ne pense pas que cela répond à la question - il n'ignore pas le reste du fichier après la première occurrence du mot recherché. –

0
awk '/word/{exit}1' file 
+0

Non, n'imprime pas la première partie de la ligne contenant le mot –

1

Pour supprimer une partie de la ligne mais, par exemple,

$ echo '12345 John Smith/red black or blue it is a test' | sed -e 's/\/.*//' 

$ 12345 John Smith 
Questions connexes