Quanto texto o grep / egrep consome toda vez?

4

Estou confuso com grep / egrep . Essas ferramentas combinam com uma única linha, eu acho? Em alguns casos, ouvi linha "lógica".

Perguntas

  1. É correto assumir que essencialmente grep / egrep sempre processa uma linha por vez até o novo caractere de linha?
  2. Eu não tenho certeza do que é a "linha lógica"?
por Jim 01.02.2014 / 21:42

2 respostas

4

A maioria das ferramentas não lê uma única linha de um arquivo de cada vez, mas usa um buffer na memória para armazenar pedaços de linhas. As ferramentas operam uma linha por vez nos dados desse buffer.

NOTA: Por "linha", quero dizer, dividir por \n , no caso de grep , ou qualquer caractere que seja indicado como "delimitador" quando a "ferramenta" for invocada .

Veja um exemplo para ilustrar esse efeito.

Dados de amostra

Crie um arquivo com 100.000 linhas nele. O arquivo é chamado afile100k.

$ for i in $(seq 100000);do echo "file$i" >> afile100k; done

Usando strace

Podemos utilizar strace para o pico dentro de um processo em execução, neste caso, o comando grep .

$ strace -s 2000 -o log100k grep 5 afile100k

Isso registrará a saída de strace , até 2000 caracteres por linha de saída, no arquivo log100k . O comando que vamos rastrear é grep 5 afile100k .

Aqui está uma saída chave do log:

ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7fff8bf73b20) = -1 ENOTTY (Inappropriate ioctl for device)

read(3, "file1\nfile2\nfile3\nfile4\nfile5\nfile6\nfile7\nfile8\nfile9\nfile10\nfile11\nfile12\nfile13\nfile14\nfile15\nfile16\nfile17\nfile18\nfile19\nfile20\nfile21\nfile22\nfile23\nfile24\nfile25\nfile26\nfile27\nfile28\nfile29\nfile30\nfile31\nfile32\nfile33\nfile34\nfile35\nfile36\nfile37\nfile38\nfile39\nfile40\nfile41\nfile42\nfile43\nfile44\nfile45\nfile46\nfile47\nfile48\nfile49\nfile50\nfile51\nfile52\nfile53\nfile54\nfile55\nfile56\nfile57\nfile58\nfile59\nfile60\nfile61\nfile62\nfile63\nfile64\nfile65\nfile66\nfile67\nfile68\nfile69\nfile70\nfile71\nfile72\nfile73\nfile74\nfile75\nfile76\nfile77\nfile78\nfile79\nfile80\nfile81\nfile82\nfile83\nfile84\nfile85\nfile86\nfile87\nfile88\nfile89\nfile90\nfile91\nfile92\nfile93\nfile94\nfile95\nfile96\nfile97\nfile98\nfile99\nfile100\nfile101\nfile102\nfile103\nfile104\nfile105\nfile106\nfile107\nfile108\nfile109\nfile110\nfile111\nfile112\nfile113\nfile114\nfile115\nfile116\nfile117\nfile118\nfile119\nfile120\nfile121\nfile122\nfile123\nfile124\nfile125\nfile126\nfile127\nfile128\nfile129\nfile130\nfile131\nfile132\nfile133\nfile134\nfile135\nfile136\nfile137\nfile138\nfile139\nfile140\nfile141\nfile142\nfile143\nfile144\nfile145\nfile146\nfile147\nfile148\nfile149\nfile150\nfile151\nfile152\nfile153\nfile154\nfile155\nfile156\nfile157\nfile158\nfile159\nfile160\nfile161\nfile162\nfile163\nfile164\nfile165\nfile166\nfile167\nfile168\nfile169\nfile170\nfile171\nfile172\nfile173\nfile174\nfile175\nfile176\nfile177\nfile178\nfile179\nfile180\nfile181\nfile182\nfile183\nfile184\nfile185\nfile186\nfile187\nfile188\nfile189\nfile190\nfile191\nfile192\nfile193\nfile194\nfile195\nfile196\nfile197\nfile198\nfile199\nfile200\nfile201\nfile202\nfile203\nfile204\nfile205\nfile206\nfile207\nfile208\nfile209\nfile210\nfile211\nfile212\nfile213\nfile214\nfile215\nfile216\nfile217\nfile218\nfile219\nfile220\nfile221\nfile222\nfile223\nfile224\nfile225\nfile226\nfile227\nfile228\nfile229\nfile230\nfile231\nfile232\nfile233\nfile234\nfile235\nfile236\nfile237\nfile238\nfile239\nfile240\nfile241\nfile242\nfile243\nfile244\nfile245\nfile246\nfile247\nfile248\nfile249\nfile250\nfile251\nfile252\nfile253\nfile254\nfile255\nfile256\nfile257\nfile258\nfile259\nfile260\nfile261\nfile262\nfile263\nfile"..., 32768) = 32768

lseek(3, 32768, SEEK_HOLE)              = 988895
lseek(3, 32768, SEEK_SET)               = 32768

Observe que grep está lendo em 32k (32768) por vez. OBSERVAÇÃO: Tentei quebrar o log um pouco para facilitar a leitura aqui no SE.

Agora começa a escrever os resultados:

fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 5), ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fcafcfff000
write(1, "file5\n", 6)                  = 6
write(1, "file15\n", 7)                 = 7
write(1, "file25\n", 7)                 = 7
write(1, "file35\n", 7)                 = 7
write(1, "file45\n", 7)                 = 7
write(1, "file50\n", 7)                 = 7

Depois de esgotar o conteúdo deste buffer, ele relerá o próximo 32k (32768) do arquivo.

write(1, "file3759\n", 9)               = 9
read(3, "\nfile3765\nfile3766\nfile3767\nfile3768\nfile3769\nfile3770\nfile3771\nfile3772\nfile3773....\nfile3986\nf"..., 32768) = 32768

Seguido por mais gravações:

write(1, "file3765\n", 9)               = 9
write(1, "file3775\n", 9)               = 9

O Grep continua a fazer isso até esgotar completamente o conteúdo do arquivo, quando termina.

write(1, "file99995\n", 10)             = 10
read(3, "", 24576)                      = 0
close(3)                                = 0
close(1)                                = 0
munmap(0x7fcafcfff000, 4096)            = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
    
por 01.02.2014 / 22:52
1

Não sei ao certo o que você sugere por uma linha lógica , mas grep (e egrep ) trabalham em linhas de entrada.

Citações de info grep :

'grep' searches input files for lines containing a match to a given pattern list. When it finds a match in a line, it copies the line to standard output (by default), or produces whatever other sort of output you have requested with options.

    
por 01.02.2014 / 21:56

Tags