Disons que j'ai un fichier contenant les deux lignes suivantes:
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
2014-05-05 09:12:17 /aa/bbbb/cccccc?dddddddd 16767
Je n'ai besoin que de la ligne contenant le motif /aa/bbbb/cccccc
, la deuxième ligne contenant des caractères supplémentaires, c'est-à-dire ?dddddddd
. Maintenant quand j'ai essayé
grep '/aa/bbbb/cccccc' file
Ensuite, les deux lignes sélectionnées. J'ai besoin de la ligne complète pour que grep -o
ne puisse pas être une solution.
Quelle pourrait être la solution possible en utilisant grep afin que seule la première ligne soit sélectionnée en fonction du modèle de recherche?
Essayez la commande grep ci-dessous qui utilise le paramètre -P
(Perl-regexp).
grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
(?<!\S)
Ce regard négatif indique que le caractère qui précède la chaîne /aa/bbbb/cccccc
serait n'importe quel caractère, mais pas un caractère non-espace.
(?!\S)
Le préfixe négatif affirme que le caractère suivant la correspondance serait n'importe quel caractère mais pas un caractère non-espace.
Un autre grep,
grep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file
En python,
script.py
#!/usr/bin/python3
import re
import sys
file = sys.argv[1]
with open(file, 'r') as f:
for line in f:
for i in line.split():
if i == "/aa/bbbb/cccccc":
print(line, end='')
Enregistrez le code ci-dessus dans un fichier et nommez-le ainsi: script.py
. Puis exécutez le script ci-dessus en
python3 script.py /path/to/the/file/you/want/to/work/with
Le moyen le plus simple serait d'ajouter un espace après votre modèle:
$ grep '/aa/bbbb/cccccc ' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Ou, pour correspondre à toutes sortes d'espaces:
$ grep '/aa/bbbb/cccccc[[:space:]]' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Ou
$ grep -P '/aa/bbbb/cccccc\s+' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Ou, avec un lookahead positif :
$ grep -P '/aa/bbbb/cccccc(?=\s)' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Ou, avec un lookahead négatif :
$ grep -P '/aa/bbbb/cccccc(?!\S)' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Ou vous pouvez inverser le match:
$ grep -v 'c?' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Ou, pour faire également correspondre les lignes qui ne contiennent que votre modèle (aucun espace de fin):
grep -P '/aa/bbbb/cccccc(\s+|$)' file
grep -E '/aa/bbbb/cccccc(\s+|$)' file
Ou, vous pouvez simplement utiliser un petit script:
En awk:
$ awk '$3=="/aa/bbbb/cccccc"' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Ou, si vous ne savez pas dans quel champ se trouve votre modèle
$ awk '{for(i=1;i<=NF;i++){if($i=="/aa/bbbb/cccccc"){print}}}' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
En Perl
$ Perl -ane 'print if grep {$_ eq "/aa/bbbb/cccccc"} @F' file
2014-05-05 09:11:53 /aa/bbbb/cccccc 29899
Pour compléter @ AvinashRajréponse , vous pouvez également utiliser une commande comme celle-ci.
grep -P '/a+/b+/c+(?!\S)' file