Formatando a saída com printf canalizado com xargs

0

Eu quero pesquisar minha base de código para ocorrências de uma seqüência de caracteres e, em seguida, obter a saída formatada como nome do arquivo, número de linha e código de lide. Comprei como queria na primeira linha da saída, mas as linhas próximas perdem a formatação desejada.

$ find src/ -name "*.js" | xargs grep --null -E -n 'filter\(|map\(' | xargs -0 printf "%-100s%-5s%-100s" > test.txt

A saída é a seguinte: (role para a direita para ver a linha completa)

src/components/AppRouterSwitch.js                                                                   15:    return _Routes.map((route, index) => {
src/components/forms/UserEditForm/UserEditForm.js36:    const options = UserTypes.map((type, index) => <option key={index} value={type.type}>{type.name}</option>);
src/components/pages/AdminPage/SolutionManagementEditPage/SolutionManagementEditPage.js119:        templates:state.templates.filter(item=>item.SOLUTIONID ==id)
src/components/pages/AdminPage/SolutionManagementEditPage/SolutionManagementEditPage.js120:            .map(item=>{return{

A primeira linha parece exatamente como eu quero. O seguinte perde a formatação desejada. Terminar a string de formato printf com /n não faz o truque.

    
por Max 13.11.2018 / 10:38

2 respostas

1

find src/ -type f -name '*.js' -exec grep -Hn -E -- 'filter\(|map\(' {} + |
    awk -F: '{printf "%-100s%-5s%-100s\n", $1, $2, substr($0, length($1) + length($2) + 3)}'

A opção -H para grep fará com que ele imprima o nome do arquivo mesmo quando chamado com um único arquivo como argumento. A opção -type f para localizar é necessária para pular links quebrados e diretórios que por acaso sejam denominados *.js .

Ou ainda mais simples, livre-se completamente do grep (graças a @don_crissti pela sugestão):

find src/ -type f -name '*.js' -exec awk '/filter\(|map\(/{printf "%-100s%-5s%-100s\n", FILENAME, FNR, $0}' {} +
    
por 13.11.2018 / 14:22
0

man deixa um pouco claro. "A varredura será interrompida na primeira correspondência" - indica que todos os nomes de arquivos serão impressos, mas a varredura da palavra correspondente será interrompida na primeira ocorrência. A página do GNU grep man esclarece isso:

-l
--files-with-matches
Suppress normal output; instead print the name of each input file from which output would normally have been printed. The scanning of each file stops on the first match. (-l is specified by POSIX.)

Aqui está um exemplo:

$grep -iR Intel * 
2018/jan/cpu.txt:Intel i9 
2018/motherboard.txt:Intel Motherboard 
hardware.txt:Intel Corei7
#the same result as you provided;

$grep -iRl Intel * 
2018/jan/cpu.txt
2018/motherboard.txt
hardware.txt
#the desired result
    
por 13.11.2018 / 11:26