J'utilise souvent grep pour trouver des fichiers ayant une certaine entrée comme celle-ci:
grep -R 'MyClassName'
La bonne chose est qu'il retourne les fichiers, leur contenu et marque la chaîne trouvée en rouge. La mauvaise chose est que j'ai également des fichiers énormes où le texte entier est écrit sur une seule grande ligne. Maintenant, grep génère trop de résultats lors de la recherche de texte dans ces gros fichiers. Existe-t-il un moyen de limiter la sortie à par exemple 5 mots à gauche et à droite? Ou peut-être limiter la sortie à 30 lettres à gauche et à droite?
command-line
text-processing
grep
Socrate
la source
la source
cut
cut
, car il se divise uniquement par délimiteur ou par nombre de caractères. Mais quand je trouve une ligne avecMyClassName
elle, elle peut être n'importe où sur la ligne et pas toujours à la même position. De plus, il peut y avoir une variation de caractères à l'avant et à l'arrière de celui-ci, ce qui rompt la possibilité de diviser par délimiteur.MyClassName
a été trouvée, je souhaite obtenir le nom du fichier et les caractères x à gauche et à droite. x est n'importe quel nombre que je fournis, par exemple 30. Le reste du contenu du fichier doit être ignoré. Il s'agit d'obtenir un contexte pour les fichiers correspondants et de limiter la surcharge.cut
s'il y a trois fichiers avec l'entrée suivante:oiadfaosuoianavMyClassNameionaernaldfajd
et/(/&%%§%/(§(/MyClassName&((/$/$/(§/$&
etpublic class MyClassName { public static void main(String[] args) { } }
?Réponses:
grep
lui-même n'a que des options de contexte basées sur des lignes. Une alternative est suggérée par ce post SU :Comme autre alternative, je suggère de
fold
saisir le texte, puis de le saluer, par exemple:L'
-s
option ferafold
pousser les mots vers la ligne suivante au lieu de les interrompre.Ou utilisez une autre méthode pour diviser l'entrée en lignes en fonction de la structure de votre entrée. (Le post SU, par exemple, traitait de JSON, donc utiliser
jq
etc. pour joli imprimer etgrep
... ou simplement utiliserjq
pour faire le filtrage par lui-même ... serait mieux que l'une des deux alternatives données ci-dessus.)Cette méthode awk GNU pourrait être plus rapide:
-v RS=...
) et le nombre de caractères dans context (-v n=...
)FNR > 1
) est celui où awk a trouvé une correspondance pour le motif.n
les derniers caractères de la ligne précédente (p
) et lesn
premiers caractères de la ligne actuelle (substr($0, 0, n)
), ainsi que le texte correspondant à la ligne précédente (qui estprt
)p
etprt
après l' impression, la valeur que nous définissons est utilisée par la ligne suivanteRT
est un GNUisme, c'est pourquoi il est spécifique à GNU awk.Pour une recherche récursive, peut-être:
la source
fold
méthode ne peut être utilisée que si vous êtes sûr que la chaîne recherchée n'apparaît pas à la bordure, sinon elle serait masquée pargrep
.gawk
. Malheureusement, la commande suggérée avec desfind
sorties aléatoires et aucun nom de fichier, lorsqu'elle est exécutée sur mon système. De plus, je ne parle pas assezawk
bien pour analyser correctement la commande. Actuellement, Regex en combinaison avecgrep
résout le problème peut-être pas rapide, mais fiable. Encore merci.RT
et le préfixe, etc. à utiliser.L'utilisation de l'appariement uniquement en combinaison avec d'autres options (voir ci-dessous), pourrait être très proche de ce que vous recherchez, sans la surcharge de traitement de l'expression régulière mentionnée dans l'autre réponse.
la source
MyClassName
. Par conséquent, le contexte manque.grep -RnHo "MyClassName"
etgrep -Rno "MyClassName"
ont la même sortie.-o
drapeau pourrait être intéressant si le regex avait une partie variable. Pour une chaîne fixe, il est inutile de l'imprimer à chaque fois. OP est très probablement intéressé par le contexte proche.-B 1
) ou après (-A 1
). Désolé de ne pas avoir pu vous aider davantage.