Script Unix pour rechercher dans un fichier compressé .gz

Je veux obtenir quelques lignes d’un fichier qui se trouve dans un fichier compressé .gz.

Le fichier .gz contient de nombreux fichiers txt et je souhaite rechercher une chaîne dans tous ces fichiers txt et obtenir les 3 lignes précédentes en sortie, y compris la ligne en cours (où la chaîne de recherche est présente).

J’ai essayé zgrep et obtenu le numéro de ligne, mais lorsque j’utilise la commande head ou tail , cela donne des valeurs de mémoire. Je pense que nous ne pouvons pas utiliser les commandes head ou tail avec des fichiers compressés contenant plusieurs fichiers.

S’il vous plaît suggérer s’il y a un moyen simple?

L’essence de la procédure consiste à obtenir les noms des fichiers dans l’archive afin de rechercher et d’extraire leur contenu pour les rechercher, sans extraire quoi que ce soit d’autre. Comme nous ne voulons pas écrire dans le système de fichiers, nous pouvons utiliser l’ -O pour extraire à la sortie standard.

tar -tzf file.tar.gz | grep '\.txt' | xargs tar -Oxzf file.tar.gz | grep -B 3 "ssortingng-or-regex" tar -tzf file.tar.gz | grep '\.txt' | xargs tar -Oxzf file.tar.gz | grep -B 3 "ssortingng-or-regex" va concaténer tous les fichiers du fichier .tar.gz dont les noms se terminent par “.txt”, et les grep pour la chaîne donnée, ainsi que les trois lignes précédentes. Il ne vous dira pas de quel fichier de l’archive provient une correspondance, et les “trois lignes précédentes” peuvent en fait provenir du fichier précédent.

Vous pouvez plutôt faire:

 for file in $(tar -tzf file.tar.gz | grep '\.txt'); do tar -Oxzf file.tar.gz "$file" | grep -B 3 --label="$file" -H "ssortingng-or-regex" done 

qui respectera les limites des fichiers et signalera les noms de fichiers, mais sera beaucoup moins efficace.

( -z indique à tar qu’il est compressé avec gzip . -t liste le contenu. -x extraits. -O redirige vers la sortie standard plutôt que vers le système de fichiers. Les anciens tar s peuvent ne pas avoir l’indicateur -O ou -z , drapeaux sans - : par exemple tar tz file.tar.gz )

Ok, vous avez donc un grep inutilisable. On peut réparer ça avec awk!

 #!/usr/bin/awk -f BEGIN { context=3; } { add_buffer($0) } /pattern/ { print_buffer() } function add_buffer(line) { buffer[NR % context]=line } function print_buffer() { for(i = max(1, NR-context+1); i <= NR; i++) { print buffer[i % context] } } function max(a,b) { if (a > b) { return a } else { return b } } 

Cela ne va pas fusionner les correspondances adjacentes, contrairement à grep -B, et peut donc répéter des lignes se trouvant à moins de 3 lignes de deux correspondances différentes.

Est-ce que c’est peut-être un gzip d’un fichier tar? Le plus simple est d’extraire le tout et d’utiliser les outils habituels sur les fichiers extraits.