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
Ceci est très trivial avec les utilitaires de traitement de texte. Par exemple, en utilisant sed
name__:
sed '1,/pattern/!d' file
Signification, faites correspondre chaque ligne de la première à celle avec pattern
et supprimez toutes les lignes qui ne correspondent pas. Donc, remplacez pattern
par 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
sed
prend 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' *
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
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
Une autre solution, en utilisant awk:
awk '/specific-pattern/{stop=1} stop==0{print}' < input_file >> output_file
Bien que la variable stop
soit é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 stop
sera défini sur 1. Cela rend stop==0
faux, donc awk n'exécutera plus l'instruction print
name__.
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.