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 renvoie les fichiers, leur contenu et marque la chaîne trouvée en rouge. Le problème, c’est que j’ai aussi d’énormes fichiers dans lesquels tout le texte est écrit en une seule 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?
grep
lui-même n'a que des options pour le contexte basé sur des lignes. Une alternative est suggérée par this post S :
Une solution de contournement consiste à activer l'option "uniquement la correspondance", puis à utiliser le pouvoir de RegExp pour grep un peu plus que votre texte:
grep -o ".\{0,50\}WHAT_I_M_SEARCHING.\{0,50\}" ./filepath
Bien sûr, si vous utilisez la mise en surbrillance des couleurs, vous pouvez toujours à nouveau grep pour colorier uniquement la correspondance réelle:
grep -o ".\{0,50\}WHAT_I_M_SEARCHING.\{0,50\}" ./filepath | grep "WHAT_I_M_SEARCHING"
Comme autre alternative, je suggérerais fold
le texte puis le renvoyer, par exemple:
fold -sw 80 input.txt | grep ...
L'option -s
permettra à fold
d'insérer des mots sur la ligne suivante au lieu de les séparer.
Ou utilisez un autre moyen de fractionner l'entrée en lignes en fonction de la structure de votre entrée. (La publication SU, par exemple, traitait de JSON. Il était donc préférable d’utiliser jq
, etc. pour imprimer de jolies lettres et grep
... ou simplement d’utiliser jq
pour effectuer le filtrage en soi ... serait préférable à l’une ou l’autre des solutions indiquées ci-dessus. .)
Cette méthode GNU awk pourrait être plus rapide:
gawk -v n=50 -v RS='MyClassName' '
FNR > 1 { printf "%s: %s\n",FILENAME, p prt substr($0, 0, n)}
{p = substr($0, length - n); prt = RT}
' input.txt
-v RS=...
) et le nombre de caractères en contexte (-v n=...
)FNR > 1
) est un enregistrement où awk a trouvé une correspondance pour le motif.n
caractères de fin de la ligne précédente (p
) et n
caractères de tête de la ligne actuelle (substr($0, 0, n)
), ainsi que le texte correspondant de la ligne précédente (qui est prt
) .p
et prt
après l’impression , la valeur que nous définissons est utilisée par la ligne suivante RT
est un GNUism, c'est pourquoi c'est GNU awk.Pour une recherche récursive, peut-être:
find . -type f -exec gawk -v n=50 -v RS='MyClassName' 'FNR>1{printf "%s: %s\n",FILENAME, p prt substr($0, 0, n)} {p = substr($0, length-n); prt = RT}' {} +
Utiliser only-matching en combinaison avec d'autres options (voir ci-dessous) peut être très proche de ce que vous recherchez, sans la charge de traitement de l'expression régulière mentionnée dans l'autre réponse.
grep -RnHo 'MyClassName'