web-dev-qa-db-fra.com

Les personnages Grep avant et après le match?

En utilisant ceci:

grep -A1 -B1 "test_pattern" file

produira une ligne avant et après le motif correspondant dans le fichier. Est-il possible d'afficher non pas des lignes mais un nombre spécifié de caractères? 

Les lignes dans mon fichier sont assez grandes, je ne suis donc pas intéressé par l’impression de la ligne entière mais plutôt par l’observation de la correspondance dans son contexte. Des suggestions sur la façon de faire ceci?

105
Legend

3 caractères avant et 4 caractères après

$> echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}'
23_string_and
grep -E -o ".{0,5}test_pattern.{0,5}" test.txt 

Cela fera correspondre jusqu'à 5 caractères avant et après votre modèle. Le commutateur -o indique à grep de n’afficher que la correspondance et -E d’utiliser une expression régulière étendue. Assurez-vous de mettre les guillemets autour de votre expression, sinon elle pourrait être interprétée par le shell.

87
ekse

Vous pourriez utiliser

awk '/test_pattern/ {
    match($0, /test_pattern/); print substr($0, RSTART - 10, RLENGTH + 20);
}' file
28
amit_g

Tu veux dire comme cela:

grep -o '.\{0,20\}test_pattern.\{0,20\}' file

?

Cela imprimera jusqu'à vingt caractères de chaque côté de test_pattern. La notation \{0,20\} est semblable à *, mais spécifie zéro à vingt répétitions au lieu de zéro ou plus. Le -o dit de ne montrer que la correspondance elle-même, plutôt que la ligne entière.

18
ruakh

Vous pouvez utiliser regexp grep pour trouver + second grep pour surligner

echo "some123_string_and_another" | grep -o -P '.{0,3}string.{0,4}' | grep string

23_string_and

enter image description here

0
Andrew Zhilin

Avec gawk, vous pouvez utiliser la fonction de correspondance:

    x="hey there how are you"
    echo "$x" |awk --re-interval '{match($0,/(.{4})how(.{4})/,a);print a[1],a[2]}'
    ere   are

Si vous êtes d'accord avec Perl, solution plus souple: Si vous suivez est imprimée trois caractères avant le motif suivi du motif actuel et ensuite 5 caractères après le motif. 

echo hey there how are you |Perl -lne 'print "$1$2$3" if /(.{3})(there)(.{5})/'
ey there how

Ceci peut également être appliqué à des mots au lieu de simples caractères. Suivre un mot avant la chaîne correspondante. 

echo hey there how are you |Perl -lne 'print $1 if /(\w+) there/'
hey

La suite imprimera un mot après le motif:

echo hey there how are you |Perl -lne 'print $2 if /(\w+) there (\w+)/'
how

La suite imprimera un mot avant le motif, puis le mot réel, puis un mot après le motif:

echo hey there how are you |Perl -lne 'print "$1$2$3" if /(\w+)( there )(\w+)/'
hey there how
0
PS.