Meu arquivo tem milhões de linhas, reside na memória /dev/shm/tmp.file
, é acessado por vários threads, fica assim
831092,25a1bd66f2eec71aa2f0a8bb3d,/path/to/a/file
4324,8d83c29e4d8c71bd66f1bd66fs,/path/to/another/file
...
e é classificado pela parte após a segunda ,
com sort -t , -k3
. Em geral, cada linha tem a forma [0-9]*,[0-9a-z]*,.*
e os caminhos de arquivo podem conter quaisquer caracteres, exceto \0
ou \n
.
Preciso extrair as linhas de todos os arquivos que residem em um determinado diretório o mais rápido possível e sem fazer uma cópia adicional. Como o arquivo é classificado dessa maneira, as linhas que estou procurando são uma parte ininterrupta do arquivo.
Atualmente eu uso, grep -F ',<directory>' /dev/shm/tmp.file
mas sei que seria muito mais rápido fazer uma busca binária para o primeiro hit e depois expandir o pedaço linha por linha ou com outra busca binária sem ler o arquivo inteiro para cada nova linha. No entanto, isso precisa ser integrado a um script bash e não encontrei como fazer algo como lseek no bash.
Existe sgrep , mas requer que as linhas completas sejam classificadas.
Como posso extrair todas as correspondências com ',<directory>'
mais rápido que grep -F
?
Edit: A entrada /dev/shm/tmp.file
existe apenas para fazer esse tipo de extração. Portanto, pré-processá-lo de alguma forma para facilitar o trabalho é uma opção.
Edit: a.b
classificar entre a
e a/b
não é um problema, pois todos os subdiretórios devem ser incluídos no bloco.
Se você mudou
831092,25a1bd66f2eec71aa2f0a8bb3d,/path/to/a/file
para/path/to/a/file,831092,25a1bd66f2eec71aa2f0a8bb3d
Você poderia fazer com:
look
é um utilitário tradicional do Unix dos anos 70, não especificado pelo POSIX, mas bastante comum. No Debian e derivados, você encontrará um nobsdmainutils
pacote, também há um no util-linux (também copiado do BSD, não no pacote Debian com o mesmo nome).look
mmap()
s o arquivo e faz uma pesquisa binária.No entanto, observe que a implementação do Debian reverte para uma pesquisa linear básica a la , a
grep
menos que você passe a-b
opção (suspiro). Então, no Debian ou derivado, você vai querer:Observe também que algumas implementações têm um limite no tamanho do arquivo que podem manipular ( veja o bug correspondente com o patch para o Debian )