No, i regex sed non hanno una corrispondenza non avida.
Puoi abbinare tutto il testo fino alla prima occorrenza di AC
utilizzando "qualsiasi cosa che non contieneAC
" seguito da AC
, che fa lo stesso di Perl .*?AC
. Il fatto è che "tutto ciò che non contiene AC
" non può essere espresso facilmente come espressione regolare: esiste sempre un'espressione regolare che riconosce la negazione di un'espressione regolare, ma la regex della negazione si complica rapidamente. E in sed portatile, questo non è affatto possibile, perché la regex di negazione richiede il raggruppamento di un'alternanza che è presente in espressioni regolari estese (ad esempio in awk) ma non in espressioni regolari di base portatili. Alcune versioni di sed, come GNU sed, hanno estensioni a BRE che lo rendono in grado di esprimere tutte le possibili espressioni regolari.
sed 's/AB\([^A]*\|A[^C]\)*A*AC/XXX/'
A causa della difficoltà di negare una regex, questo non si generalizza bene. Quello che puoi fare invece è trasformare temporaneamente la linea. In alcune implementazioni di sed, è possibile utilizzare newline come marker, poiché non possono apparire in una riga di input (e se sono necessari più marker, utilizzare newline seguito da un carattere variabile).
sed -e 's/AC/\
&/g' -e 's/AB[^\
]*\nAC/XXX/' -e 's/\n//g'
Tuttavia, attenzione che backslash-newline non funziona in un set di caratteri con alcune versioni sed. In particolare, ciò non funziona in GNU sed, che è l'implementazione di sed su Linux non incorporato; in GNU sed puoi usare\n
invece :
sed -e 's/AC/\
&/g' -e 's/AB[^\n]*\nAC/XXX/' -e 's/\n//g'
In questo caso specifico, è sufficiente sostituire il primo AC
con una nuova riga. L'approccio che ho presentato sopra è più generale.
Un approccio più potente in sed è quello di salvare la linea nello spazio di trattenimento, rimuovere tutto tranne la prima parte "interessante" della linea, scambiare lo spazio di trattenuta e lo spazio del motivo o aggiungere lo spazio del motivo allo spazio di trattenimento e ripetere. Tuttavia, se inizi a fare cose così complicate, dovresti davvero pensare di passare a awk. Awk non ha neanche una corrispondenza non avida, ma puoi dividere una stringa e salvare le parti in variabili.