Con pcregrep
:
pcregrep -rMl '^C.*\nC' .
POSIXly:
find . -type f -exec awk '
FNR==1 {last=0; printed=0; next}
printed {next}
/^C/ {if (last) {print FILENAME; printed=1; nextfile} else last=1; next}
{last=0}' {} +
(sebbene ciò significhi leggere completamente tutti i file con quelle awk
implementazioni che non supportano nextfile
).
Con versioni di GNU grep
fino alla 2.5.4:
grep -rlP '^C.*\nC' .
sembra funzionare, ma è per caso e non è garantito che funzioni.
Prima che fosse risolto in 2.6 (con questo commit ), GNU grep
aveva trascurato che la funzione di ricerca pcre che stava usando corrispondeva all'intero buffer attualmente elaborato grep
, causando ogni tipo di comportamento sorprendente. Per esempio:
grep -P 'a\s*b'
corrisponderebbe a un file contenente:
bla
bla
Questo corrisponderebbe:
printf '1\n2\n' | grep -P '1\n2'
Ma questo:
(printf '1\n'; sleep 1; printf '2\n') | grep -P '1\n2'
O:
(yes | head -c 32766; printf '1\n2\n') > file; grep -P '1\n2' file
no (dato che 1\n2\n
è attraverso due buffer elaborati da grep
).
Quel comportamento finì per essere documentato però:
15- Come posso abbinare tra le linee?
Il grep standard non può farlo, poiché è fondamentalmente basato sulla linea. Pertanto, il semplice utilizzo della classe di caratteri "[: space:]" non corrisponde alle nuove righe nel modo previsto. Tuttavia, se il tuo grep è compilato con gli schemi Perl abilitati, il modificatore del 's' (che rende '.' Corrispondente alle nuove righe) può essere usato:
printf 'foo\nbar\n' | grep -P '(?s)foo.*?bar'
Dopo che è stato corretto in 2.6, la documentazione non è stata modificata (una volta l'ho riportata lì ).
C
nel tuo secondo esempio.