J'ai deux fichiers, file1
et file2
.
Le contenu de l'échantillon de file1
est:
A B
C D
E F
G H
et le contenu de file2
est comme:
A B
few other lines
E F
few more other lines
A B
C D
E F
G H
few more other lines
G H
Je souhaite donc rechercher le bloc de file1
contenu entier file2
uniquement. Cela signifie que la sortie ne doit contenir que ces lignes:
A B
C D
E F
G H
veuillez noter que: - seules les lignes qui se rejoignent devraient faire partie de la sortie.
shell-script
text-processing
awk
sed
sachin
la source
la source
file1
et rien d'autre, utilisez simplementcat file1
.Réponses:
grep
est assez stupide en ce qui concerne les modèles multilignes, mais la traduction de tous les caractères\n
de nouvelle ligne du modèle et du texte pour rechercher en caractères NUL\0
avant de les comparer résout ce problème. Il est évidemment également nécessaire de traduire\0
dans la sortie vers\n
.Voici votre commande, en supposant qu'elle
file1
contient le modèle dans lequel vous souhaitez rechercherfile2
:Exemple de sortie pour vos fichiers donnés:
Explication:
<(tr '\n' '\0' < file1)
crée un objet semblable à un fichier FIFO / nommé pipe / temporaire égal àfile1
, mais avec tous les caractères de nouvelle ligne traduits en caractères NUL.<(tr '\n' '\0' < file2)
fait de même, mais pourfile2
.grep -f PATTERN_FILE INPUT_FILE
recherche le motif (s) à partirPATTERN_FILE
deINPUT_FILE
.-a
drapeau degrep
permet la correspondance sur les fichiers binaires. Ceci est nécessaire car sinon il ignorerait les fichiers contenant des caractères non imprimables comme\0
.-o
drapeau degrep
fait qu'il imprime uniquement la séquence correspondante, pas toute la ligne où il a été trouvé.| tr '\0' '\n'
convertit tous les caractères NUL de la sortie de la commande sur le côté gauche en caractères de nouvelle ligne.la source
Ce qui suit est maladroit, mais fonctionne avec GNU
awk
:la source
Juste pour le plaisir en pure bash
la source
Voici un peu plus élégant
grep
+perl
:Cependant, il y a un gros problème. S'il y a un saut de ligne final dans
file1
, le modèle ne sera pas correct, autrement dit:A B\nC D\nE F\nG H\n\n
.(Merci spécial @terdon pour avoir fourni la partie perl)
Comme costas l'a noté, on peut utiliser
perl -0pe 's/\n(\n+$)?/\\n/g'
à la place de l'autreperl
commande pour éviter la nouvelle ligne de fin dans lefile1.txt
la source
perl -0pe 's/\n(\n+$)?/\\n/g'
. Sans-0
leg
modificateur d'expression régulière est en sus.Je ne sais pas trop ce que vous voulez que la sortie soit, mais c'est facile à faire avec des langues qui ne sont pas exclusivement orientées ligne (surtout si les deux fichiers peuvent être lus en mémoire). Voici un script python qui vous indiquera le nombre de correspondances.
Vous souhaitez imprimer
file1
autant de fois que cela correspond? Remplacez la dernière ligne par ceci:Vous pouvez tout regrouper dans un appel ou un alias de ligne de commande, si vous voulez vraiment:
la source
le résultat sera tous les fichiers avec une correspondance de texte exacte
la source
Voici une autre approche utilisant python (testé avec
python3 3.5.2
, sans aucune plainte depylint3 1.5.6
):La gestion des arguments de ligne de commande via
sys.argv
est certes simpliste. Vous pouvez faire bien d'autres choses avec la valeur de retour definder
sur les deuxmemoryview
objets que vous transmettez, en plus de la transmettretuple
. ChaqueSRE_Match
élément fourni par l'itérateur renvoyé parfinder
possède une variété de méthodes, dont un échantillonnage est résumé dans laprint
sortie (lespan
, par exemple, indique la plage d'octets de chaque correspondance).la source