PDA

Ver Versão Completa : Sobre o comando greg do linux



gu1le
13-05-2017, 05:39
Maio-2017



Como sempre, pesquisei na internet encontrei informações. Separei as que achei mais interessantes para mim e montei esta anotação para eu usar. Dá para eu ter pelo menos uma noção do que é o comando grep. Espero que minha anotação lhe seja util. Ela é útil para mim.


O significado do nome é (Globally Search a Regular Expression and Print)


O Grep procura texto em uma string ou dentro de arquivos e mostra linhas, ocorrências. O Grep usa combinações para pesquisar e o resultado da pesquisa pode ser mostrado na tela.



O grep já vem instalado no Linux.


Digitando apenas o comando e dando enter ele não faz nada, mas se digito um parâmetro tipo -V já posso saber a versão do grep que tenho instalado no meu Linux.


$ grep -V
grep (GNU grep) 3.0
Copyright (C) 2017 Free Software Foundation, Inc.
Licença GPLv3+: GNU GPL versão 3 ou superior <http://gnu.org/licenses/gpl.html>.
Este é um software livre: você é livre para alterá-lo e redistribuí-lo.
NÃO HÁ GARANTIAS, na máxima extensão permitida por lei.

Escrito por Mike Haertel e outros, veja <http://git.sv.gnu.org/cgit/grep.git/tree/AUTHORS>




Alguns parâmetros que posso usar e suas respectivas funções:



PARÂMETROS E SUAS FUNÇÕES:





-c


Conta quantas vezes apareceu a string que esta pesquisando



-v


Mostra na tela “tudo” menos onde houver a ocorrência da string pesquisada



-i


Realiza uma busca pela string ignorando o case, sendo case-insensitive



-o


Ira mostrar na tela apenas as ocorrências da string pesquisada ignorando o resto



-n


Ira mostrar na tela na primeira coluna a linha onde encontrou a string pesquisada



-B


Numero de linhas a serem impressas antes da linha que contem a string pesquisada [BEFORE]



-A


Numero de linhas a serem impressas na tela depois da encontrar a linha com a string [AFTER]



-C


Quantidade de linhas antes e depois da linha que contem a string [CONTEXT]



-q


Ira procurar pela string informada, porém estará em modo silencioso, nada sera impresso na tela, porém caso encontre o comando encerra com 0, caso não encontre nada será 1



-E


Extende o uso de Regex no padrão e combinação, usando logica AND e OR por exemplo



-f


Um arquivo com combinações de padrões com Regex, podendo usar varias combinações



-l


Mostra somente o nome do arquivo onde foi encontrado a string pesquisada



-L


Semelhante ao -v, porque mostra apenas os arquivo que não contem a string informada



-h


Pesquisa varias arquivos, diretórios se com -r mas não mostra o nome dos arquivos



-r


Ira realizar uma pesquisa recursiva em todos os diretórios a partir do informado



--color


Deve-se passar o parâmetro ‘never’ caso não queira que a saída marque com cor a string ou ‘auto’ e ‘always’ para operar conforme necessite. Pode mudar a cor alterando GREP_COLOR, GREP_COLORS no environment





Crio um arquivo chamado palavras.txt coloco um texto dentro e brinco com o grep.



echo -ne "amor\ncasa\nCasa\nCASA\nRaspberryPI\nRaspberry PI\nRaspberry B PI\nArduino\narduino\nARDUINO\nIDEArduino\nLinux é o poder\nEu programo Python e você?\n" > palavras.txt





Visualizo o arquivo que criei:



$ cat palavras.txt
amor
casa
Casa
CASA
RaspberryPI
Raspberry PI
Raspberry B PI
Arduino
arduino
ARDUINO
IDEArduino
Linux é o poder
Eu programo Python e você?




Uso o grep para pesquisar pela string “Raspberry“, posso usar de duas maneiras:




Com o cat um pipe e logo em seguida um grep ou diretamente com o comando.



A primeira opção é muito utilizada, porém perde performance caso eu realize pesquisa em muitos arquivo ou em um arquivo longo.




$ cat palavras.txt | grep "Raspberry"
RaspberryPI
Raspberry PI
Raspberry B PI



$ grep "Raspberry" palavras.txt
RaspberryPI
Raspberry PI
Raspberry B PI





Caso eu queira contar o numero de ocorrências da string “Raspberry”:



$ grep -c "Raspberry" palavras.txt
3





Se eu quiser ver tudo menos a string que contenham “Raspberry”:



$ grep -v "Raspberry" palavras.txt
amor
casa
Casa
CASA
Arduino
arduino
ARDUINO
IDEArduino
Linux é o poder
Eu programo Python e você?





Agora quero pesquisar pela string “arduino”.



$ grep "arduino" palavras.txt
arduino



$ grep "arduino" palavras.txt
arduino




Tenho Arduino escrito de diversas maneiras, então vou executar o grep para ser case-insensitive.



$ grep -i "arduino" palavras.txt
Arduino
arduino
ARDUINO
IDEArduino





E se no lugar de mostrar a linha inteira ou o que estiver junto eu mostrar apenas a string procurada.



$ grep -o "arduino" palavras.txt
arduino


$ grep -oi "arduino" palavras.txt
Arduino
arduino
ARDUINO
Arduino


$ grep -oi "Raspberry" palavras.txt
Raspberry
Raspberry
Raspberry




Se eu precisar saber o numero da linha onde foi encontrada a string.


$ grep -n "Raspberry" palavras.txt
5:RaspberryPI
6:Raspberry PI
7:Raspberry B PI


$ grep -n "duino" palavras.txt
8:Arduino
9:arduino
11:IDEArduino




Agora vou pesquisar pela string “arduino” e obter também as 2 linhas antes da string encontrada.


$ grep "arduino" -B 2 palavras.txt
Raspberry B PI
Arduino
arduino




O mesmo posso fazer obtendo as linhas depois da linha com a string pesquisada.


$ grep "arduino" -A 2 palavras.txt
arduino
ARDUINO
IDEArduino




Posso unir as duas opções, pegando e imprimindo linhas antes e depois da linha que contem a string pesquisada.


$ grep "arduino" -C 2 palavras.txt
Raspberry B PI
Arduino
arduino
ARDUINO
IDEArduino




Caso eu não queira mostrar nada na tela, só saber se teve sucesso ou não na pesquisa.



$ grep -q "arduino" palavras.txt
$ echo $?
0

$ grep -q "Beaglebone" palavras.txt
$ echo $?
1



No exemplo acima pesquisei a string “arduino” com o parâmetro -q (modo silencioso) e peguei a saída do ultimo comando executado com (echo $?), logo em seguida pesquisei por “Beaglebone” como não existe a saída foi 1.






Vou brincar com outros parâmetros. Desta vez vou criar mais 2 arquivos sistema.txt e hardware.txt, e também copiar a saída do dmesg para dmesg.log e brincar com estes caras.







Preparo os arquivos:




$ echo -ne "Linux Ubuntu\nLinux Debian\nLinux Mint\nLinux CentOS\nRaspbian\nYocto RaspberryPI\nBuildroot RaspberryPI\n" > sistema.txt

$ echo -ne "ARM 1176JZF\mARM Cortex-A7\nBCM2835\nBCM2836\nBeaglebone Black\nAM3358\n" > hardware.txt

$ dmesg > dmesg.log





Eu criei sistema.txt e hardware.txt com palavras aleatórias.





Agora eu quero pesquisar em qualquer arquivo e que contenha a string “Raspberry”.



$ grep "Raspberry" *
palavras.txt:RaspberryPI
palavras.txt:Raspberry PI
palavras.txt:Raspberry B PI
sistema.txt:Yocto RaspberryPI
sistema.txt:Buildroot RaspberryPI



$ grep "Raspberry" ./*
./palavras.txt:RaspberryPI
./palavras.txt:Raspberry PI
./palavras.txt:Raspberry B PI
./sistema.txt:Yocto RaspberryPI
./sistema.txt:Buildroot RaspberryPI






Os demais parâmetros anteriores se aplicam aqui também.





$ grep -n "Raspberry" *
palavras.txt:5:RaspberryPI
palavras.txt:6:Raspberry PI
palavras.txt:7:Raspberry B PI
sistema.txt:6:Yocto RaspberryPI
sistema.txt:7:Buildroot RaspberryPI





Agora se eu criar um diretório exemplo/ e mover o palavras.txt para ele será que vai encontrar a string “Raspberry” nele ainda?





$ mkdir exemplo && mv palavras.txt exemplo/
$ grep "Raspberry" *
grep: exemplo: Is a directory
sistema.txt:Yocto RaspberryPI
sistema.txt:Buildroot RaspberryPI





Ele avisa que existe um diretório onde esta sendo feita a pesquisa, para que ele acesse o(s) diretório(s) deve-se passar o parâmetro -r para recursividade.





$ grep -r "Raspberry" *
exemplo/palavras.txt:RaspberryPI
exemplo/palavras.txt:Raspberry PI
exemplo/palavras.txt:Raspberry B PI
sistema.txt:Yocto RaspberryPI
sistema.txt:Buildroot RaspberryPI






As vezes só interessa saber a ocorrências mas não o arquivo.





$ grep -hr "Raspberry" *
RaspberryPI
Raspberry PI
Raspberry B PI
Yocto RaspberryPI
Buildroot RaspberryPI





Caso eu queira apenas saber qual arquivo contem a string mas não precisa mostrar ela.




$ grep -lr "Raspberry" *
exemplo/palavras.txt
sistema.txt





E se quiser saber os arquivos que não possuem a string pesquisada.





$ grep -Lr "Raspberry" *
dmesg.log
hardware.txt





Habilitando ou não o uso da saída colorida.





$ grep -r --color=always "Raspberry" *
exemplo/palavras.txt:RaspberryPI
exemplo/palavras.txt:Raspberry PI
exemplo/palavras.txt:Raspberry B PI
sistema.txt:Yocto RaspberryPI
sistema.txt:Buildroot RaspberryPI

$ grep -r --color=never "Raspberry" *
exemplo/palavras.txt:RaspberryPI
exemplo/palavras.txt:Raspberry PI
exemplo/palavras.txt:Raspberry B PI
sistema.txt:Yocto RaspberryPI
sistema.txt:Buildroot RaspberryPI







Agora com o básico de Expressões Regulares, e como exemplo usaremos o dmesg.log gerado acima.


Fazendo uma busca simples pela string “usb”.





$ grep "usb" dmesg.log
[ 0.668550] usbcore: registered new interface driver usbfs
[ 0.668558] usbcore: registered new interface driver hub
[ 0.668582] usbcore: registered new device driver usb
[ 1.996732] usb usb1: New USB device found, idVendor=1d6b, idProduct=0002
[ 1.996735] usb usb1: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1.996737] usb usb1: Product: EHCI Host Controller
[ 1.996739] usb usb1: Manufacturer: Linux 3.13.0-37-generic ehci_hcd
[ 1.996741] usb usb1: SerialNumber: 0000:00:1d.0
[ 1.997338] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
[ 1.997340] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1.997342] usb usb2: Product: xHCI Host Controller
[ 1.997344] usb usb2: Manufacturer: Linux 3.13.0-37-generic xhci_hcd
[ 1.997346] usb usb2: SerialNumber: 0000:00:14.0
[ 2.000099] usb usb3: New USB device found, idVendor=1d6b, idProduct=0003
[ 2.000101] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 2.000103] usb usb3: Product: xHCI Host Controller
[ 2.000105] usb usb3: Manufacturer: Linux 3.13.0-37-generic xhci_hcd
[ 2.000107] usb usb3: SerialNumber: 0000:00:14.0
[ 2.308561] usb 1-1: new high-speed USB device number 2 using ehci-pci
[ 2.440791] usb 1-1: New USB device found, idVendor=8087, idProduct=8000
[ 2.440794] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 2.712387] usb 1-1.5: new full-speed USB device number 3 using ehci-pci
[ 2.805614] usb 1-1.5: New USB device found, idVendor=0cf3, idProduct=0036
[ 2.805616] usb 1-1.5: New USB device strings: Mfr=0, Product=0, SerialNumber=0
[ 2.880293] usb 1-1.7: new high-speed USB device number 4 using ehci-pci
[ 2.972951] usb 1-1.7: New USB device found, idVendor=0bda, idProduct=0129
[ 2.972954] usb 1-1.7: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 2.972956] usb 1-1.7: Product: USB2.0-CRW
[ 2.972958] usb 1-1.7: Manufacturer: Generic
[ 2.972959] usb 1-1.7: SerialNumber: 20100201396000000
[ 3.044205] usb 1-1.8: new high-speed USB device number 5 using ehci-pci
[ 3.201201] usb 1-1.8: New USB device found, idVendor=0c45, idProduct=64af
[ 3.201203] usb 1-1.8: New USB device strings: Mfr=2, Product=1, SerialNumber=0
[ 3.201205] usb 1-1.8: Product: Laptop_Integrated_Webcam_HD
[ 3.201206] usb 1-1.8: Manufacturer: CN0Y3PX8724873AGB17FA01
[ 14.243360] usbcore: registered new interface driver btusb
[ 14.274681] usbcore: registered new interface driver rts5139
[ 14.624063] input: Laptop_Integrated_Webcam_HD as /devices/pci0000:00/0000:00:1d.0/usb1/1-1/1-1.8/1-1.8:1.0/input/input13
[ 14.624169] usbcore: registered new interface driver uvcvideo
[ 14.761434] usbcore: registered new interface driver ath3k
[ 14.781788] usb 1-1.5: USB disconnect, device number 3
[ 14.981529] usb 1-1.5: new full-speed USB device number 6 using ehci-pci
[ 20.075906] usb 1-1.5: New USB device found, idVendor=0cf3, idProduct=0036
[ 20.075911] usb 1-1.5: New USB device strings: Mfr=0, Product=0, SerialNumber=0






Bastante coisa. Vou trabalhar em cima extendendo os recursos de Regex da expressão, por exemplo quero somente as linhas que contenham usb2 OU usb3, aplicando a logica OR.






$ grep -E "usb2|usb3" dmesg.log
[ 1.997338] usb usb2: New USB device found, idVendor=1d6b, idProduct=0002
[ 1.997340] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 1.997342] usb usb2: Product: xHCI Host Controller
[ 1.997344] usb usb2: Manufacturer: Linux 3.13.0-37-generic xhci_hcd
[ 1.997346] usb usb2: SerialNumber: 0000:00:14.0
[ 2.000099] usb usb3: New USB device found, idVendor=1d6b, idProduct=0003
[ 2.000101] usb usb3: New USB device strings: Mfr=3, Product=2, SerialNumber=1
[ 2.000103] usb usb3: Product: xHCI Host Controller
[ 2.000105] usb usb3: Manufacturer: Linux 3.13.0-37-generic xhci_hcd
[ 2.000107] usb usb3: SerialNumber: 0000:00:14.0





Vou pesquisar por uma linha que contenha “usb” E tambem “Product:”, vou aplicar a logica AND.





$ grep -E "usb.*Product:" dmesg.log
[ 1.996737] usb usb1: Product: EHCI Host Controller
[ 1.997342] usb usb2: Product: xHCI Host Controller
[ 2.000103] usb usb3: Product: xHCI Host Controller
[ 2.972956] usb 1-1.7: Product: USB2.0-CRW
[ 3.201205] usb 1-1.8: Product: Laptop_Integrated_Webcam_HD





Mas eu quero só com “usb2” ou “usb3” casando com “Product:”.





$ grep -E "usb(2|3).*Product:" dmesg.log
[ 1.997342] usb usb2: Product: xHCI Host Controller
[ 2.000103] usb usb3: Product: xHCI Host Controller





Posso aplicar varias combinações com Expressões Regulares.





Posso criar um arquivo com o meu Regex e usar ele como padrão, alias, podemos colocar varias combinações neste arquivo.





$ echo "usb(2|3).*Product:" > meu_regex
$ cat meu_regex
usb(2|3).*Product:
$ grep -f meu_regex -E dmesg.log
[ 1.997342] usb usb2: Product: xHCI Host Controller
[ 2.000103] usb usb3: Product: xHCI Host Controller





Vou usar o grep direto e usar ele com qualquer comando um pipe e logo em seguida o grep.



Vou fazer uma pesquisa no /var/log/syslog.1 por quantas ocorrências da string “info” usando cat e o grep direto.





$ time cat /var/log/syslog.1 | grep -c "info"
1027

real 0m0.011s
user 0m0.005s
sys 0m0.008s


$ time grep -c "info" /var/log/syslog.1
1027

real 0m0.009s
user 0m0.009s
sys 0m0.000s





Para desempenho de uso em grande escala do grep é setar LC_ALL=C antes:





$ strace -c grep -c "info" /var/log/syslog.1
187
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
27.03 0.000160 11 14 mmap
14.19 0.000084 8 10 read
13.18 0.000078 13 6 open
11.15 0.000066 8 8 mprotect
9.63 0.000057 11 5 5 access
5.57 0.000033 4 9 fstat
4.56 0.000027 3 9 close
3.55 0.000021 11 2 munmap
3.55 0.000021 7 3 brk
3.04 0.000018 18 1 execve
1.52 0.000009 9 1 write
1.35 0.000008 4 2 1 ioctl
1.35 0.000008 8 1 openat
0.34 0.000002 2 1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 0.000592 72 6 total

$ export LC_ALL=C

$ strace -c grep -c "info" /var/log/syslog.1
187
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
20.07 0.000114 11 10 read
16.73 0.000095 8 12 mmap
16.20 0.000092 12 8 mprotect
6.87 0.000039 8 5 5 access
6.16 0.000035 9 4 open
6.16 0.000035 18 2 munmap
5.99 0.000034 34 1 execve
5.46 0.000031 10 3 brk
4.40 0.000025 4 7 close
3.87 0.000022 3 7 fstat
2.99 0.000017 17 1 write
2.64 0.000015 15 1 openat
1.94 0.000011 6 2 1 ioctl
0.53 0.000003 3 1 arch_prctl
------ ----------- ----------- --------- --------- ----------------
100.00 0.000568 64 6 total





Novamente verificando o tempo apos setar LC_ALL=C.





$ time grep -c "info" /var/log/syslog.1
187

real 0m0.003s
user 0m0.003s
sys 0m0.000s


$ time cat /var/log/syslog.1 | grep -c "info"
187

real 0m0.005s
user 0m0.000s
sys 0m0.009s





No meu syslog.1 não deu tanta diferença, mas fazer essa varredura em um aquivo de 500M você notara uma grande diferença.







Fonte (http://cleitonbueno.com/)







videos-youtube-estudos-linux-links:




https://www.youtube.com/watch?v=t9Bsozz3Jmw



https://youtu.be/A4yngkJ3m7s



https://youtu.be/ufWrWK0I2o0



https://youtu.be/kHQLll3uGIQ



https://youtu.be/GtWmaI_l3Y8



https://youtu.be/a_bdu6Bhyes


https://youtu.be/psugMHhj0sc



.

darksidebr
14-05-2017, 16:10
Obrigado @gu1le (http://tocadacoruja.net/forum/member.php/60833-gu1le).