web-dev-qa-db-fra.com

Comment trouver des lignes correspondant à un motif et les supprimer?

Dans un fichier contenant beaucoup de lignes, je souhaite supprimer les lignes commençant par HERE IT IS.

Comment puis-je faire cela en utilisant uniquement des outils de ligne de commande?

13
micgeronimo

Essayez sed:

sed -i '/^HERE IT IS/d' <file>

ATTENTION: Il est préférable de faire une sauvegarde lorsque vous utilisez le -i commutateur de sed:

sed -i.bak '/^HERE IT IS/d' <file>

Le fichier d'origine restera en tant que <file>.bak et le fichier modifié sera <file>.

28
heemayl

En plus des très bonnes réponses que vous avez reçues, grepet sedname__, voici d'autres outils qui peuvent faire la même chose:

  • Quelques manières de Perl:

    Perl -ne '/^HERE IT IS/ || print' file > newfile
    Perl -ne 'print if !/^HERE IT IS/' file > newfile
    Perl -ne 'print unless /^HERE IT IS/' file > newfile
    

    Vous pouvez ajouter le commutateur -i à n’importe quel exemple pour éditer le fichier à la place:

    Perl -i.bak -ne '/^HERE IT IS/ || print' file        
    
  • (rester bouche bée

    awk '!/^HERE IT IS/' file > newfile
    

    Les versions plus récentes (4.1.1 et supérieures) de GNU awk(le awkpar défaut sous Linux) peuvent également modifier le fichier à la place:

    gawk -i inplace  '!/^HERE IT IS/' file
    
  • Shell (bashname__, zshname__, kshname__, probablement d'autres). C’est un peu bête, mais peut être fait, mais d’autres outils sont meilleurs.

    while IFS= read -r line; do 
      [[ $line =~ ^"HERE IT IS" ]] || printf "%s\n" "$line"
    done < file > newfile
    
16
terdon

J'utiliserais grep pour les filtrer. Par exemple :

grep -v "^HERE IT IS" infile > outfile

Puis déplacez le fichier arrière vers infile.

13
Ben Hills

sed est définitivement la voie à suivre.

Cette légère modification de la commande @heemayl vous a donné supprime la ligne, que le même cas soit utilisé dans le motif ou non, en raison du I dans la référence du motif.

sed -i '/HERE IT IS/Id' <file>

Si vous vouliez faire cela sur plusieurs fichiers d'un répertoire, vous pouvez le combiner avec find comme ceci.

find . -maxdepth 1 -type f -exec sed -i.bak '/HERE IT IS/Id' {} +

L'option maxdepth signifie que cela ne sera pas recurse dans les répertoires.

5
Arronical

Grep

grep -P '^(?!HERE IT IS)' file

(?!HERE IT IS) assertion lookahead négative qui oblige le moteur des expressions rationnelles à correspondre à toutes les limites de départ de la ligne ( qui correspondent généralement à ^) uniquement si elles ne sont pas suivies par la chaîne HERE IT IS

python

#!/usr/bin/python3
import sys
fil = sys.argv[1]
with open(fil) as f:
    for line in f:
        if not line.startswith('HERE IT IS'):
            print(line, end="")

Enregistrez le script dans un fichier, dites script.py, puis exécutez-le à l'aide de la commande ci-dessous sur le terminal.

python3 script.py infile
4
Avinash Raj

Une autre option python:

#!/usr/bin/env python3
[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]

Où f est le chemin du fichier, entre guillemets.

4
Jacob Vlijm

Vous pouvez utiliser Vim en mode Ex:

ex -sc 'g/^HERE IT IS/d' -cx file
  1. g recherche globale

  2. d delete

  3. x save and close

1
Steven Penny