web-dev-qa-db-fra.com

Supprimer les lignes qui suivent une ligne avec un motif spécifique dans Shell

J'essaie de supprimer toutes les lignes qui suivent un modèle spécifique dans les fichiers.

J'ai plusieurs fichiers qui ont tous la même structure:

Exemple:

fichier1

line 1
...
line x "here there is a specific pattern"
...
EOF

fichier n

line 1
...
line x "here there is a specific pattern"
...
EOF

J'ai essayé de trouver une solution simple, mais comme j'ai beaucoup de fichiers, je continue avec un long chemin: p

Le motif apparaît une fois dans chaque fichier.

Donc, j'ai tous les numéro de lignes qui contient ce modèle, et enregistrez dans un fichier.

c'est mon code:

count=$(ls -f path_to_folder/*.txt | wc -l)
echo "Number of txt file : $count"
###


    for ((i=1;i < $count+1 ;i++))

    {

    vt=$(grep -n PATTERN $i.txt | cut -d : -f 1)
    echo $vt >> PATTERN_line.txt

    }

Chaque ligne de PATTERN_line.txt contient le numéro de ligne, dans chaque fichier, où le modèle existe.

Maintenant, j'essaie d'utiliser ces nombres pour supprimer toutes les lignes qui suivent le motif jusqu'à la fin du fichier.

Cela signifie que je dois garder le fichier de la tête à la ligne de patten qui doit être inclus.

J'apprécie ton aide

4
MGM

Ceci est très trivial avec les utilitaires de traitement de texte. Par exemple, en utilisant sedname__:

sed '1,/pattern/!d' file

Signification, faites correspondre chaque ligne de la première à celle avec patternet supprimez toutes les lignes qui ne correspondent pas. Donc, remplacez patternpar votre modèle. S'il contient /, vous devez échapper à ces caractères. Par exemple, si le modèle est pattern-with/character:

sed '1,/pattern-with\/character/!d' file

Pour éditer réellement des fichiers (plutôt que d'imprimer le flux édité sur stdout), vous pouvez utiliser l'indicateur -i:

sed -i '1,/pattern/!d' file

Vous pouvez faire une sauvegarde du fichier d'origine en ajoutant une extension pour l'ancien fichier à -i. Faites attention ici - vous ne devez pas inclure d'espace avant l'extension.

sed -i.backup '1,/pattern/!d' file

sedprend plusieurs arguments de nom de fichier. Par exemple, pour agir sur tous les fichiers non cachés du répertoire actuel, vous pouvez utiliser:

sed -i '1,/pattern/!d' *
10
Zanna

Merci @ Zanna

J'ai trouvé cette solution:

for ((i=1;i < $count+1 ;i++)) 

sed -n '/PATTERN/q;p' $i.txt > file_out$i.txt

Je vous remercie

0
MGM

Essayez ce script shell. Il faut 2 arguments en entrée. Le premier argument est le nom du fichier d'entrée. Et le deuxième argument est le motif requis pour la recherche. Il supprimera les lignes après la première correspondance du motif.

#!/bin/bash

touch temp.txt

while read line
do
    echo "$line" | grep "$2" &> /dev/null
    if [ $? -eq 0 ]
    then
        echo "$line" >> temp.txt
        mv temp.txt $1
        echo "STATUS: Pattern matched. Successful operation..."
        exit 0
    fi
    echo "$line" >> temp.txt
done < $1

echo "STATUS: Pattern not found. No lines are deleted..."
rm -f temp.txt
0
Ranajit Hore

Une autre solution, en utilisant awk:

awk '/specific-pattern/{stop=1} stop==0{print}' < input_file >> output_file

Bien que la variable stopsoit égale à 0 (c'est-à-dire, par défaut), awk affichera la ligne en cours. Toutefois, si la ligne en cours correspond à expression régulière /specific-pattern /, alors stopsera défini sur 1. Cela rend stop==0 faux, donc awk n'exécutera plus l'instruction printname__.

L'entrée est lue à partir du fichier input_file et ajoutée au fichier output_file.

Si vous souhaitez conserver la ligne avec le motif, inversez les deux parties du script awk.

0
user234461