Come cercare un file di text per le stringhe tra due gettoni nel terminal di Ubuntu e salvare l'output?

Come posso cercare un file di text per questo model nel terminal Ubuntu e salvare l'output come file di text?

Sto cercando tutto tra la string "abc" e la string "cde" in un lungo elenco di dati.

Per esempio:

blah blah abc fkdljgn cde blah blah blah blah blah blah abc skdjfn cde blah 

Nell'esempio precedente cercherò un'output come questa:

 fkdljgn skdjfn 

È importnte salvare l'output dei dati come file di text.

Posso usare grep o agrep e, in caso affermativo, qual è il formato?

Per get l'output che mostri, puoi eseguire

 grep -Po 'abc \K.*(?= cde)' file.txt > outfile.txt 

Il P triggers espressioni regolari Compatibili Perl che hanno il supporto per lookarounds e \K che significa "scartare qualcosa accostato a questo punto". Il -o causa grep per printingre solo la parte corrispondente della linea in modo combinata con il lookahead positivo ( ?=cde ) e \K , stamperà solo i caratteri tra abc e cde . Il > outfile.txt salverà il risultato nel file outfile.txt .

Alcuni altri approcci:

  • sed

     sed -r 's/.*abc (.+) cde.*/\1/' file.txt > outfile.txt 

    Qui le parentesi catturano il model e si può quindi fare riferimento come \1 . Il 's/source/replacement/' è l'operatore di sostituzione e sostituisce la source con la replacement . In questo caso, elimina semplicemente tutto tranne qualunque cosa sia tra abc e cde .

  • perl

     perl -pe 's/.*abc (.+) cde.*/$1/' file.txt > outfile.txt 

    Come detto sopra, il -p significa "leggere la row di file di input per row, applicare lo script dato come -e e printingre.

  • awk

      awk -F'abc|cde' '{print $2}' file.txt > outfile.txt 

    L'idea qui è di impostare i delimitatori di field ad abc o cde . Supponendo che queste stringhe siano uniche in each row, il secondo field sarà quello tra i due. Ciò, tuttavia, include gli spazi principali e finali, per rimuoverli passano attraverso un altro awk :

     awk -F'abc|cde' '{print $2}' file | awk '{print $1}' 
  • GNU awk ( gawk ). Quanto sopra funziona perfettamente anche in gawk , sono incluso nel caso in cui si voglia fare qualcosa di più complesso e deve essere in grado di catturare templates.

     gawk '{print gensub(/.*abc (.*) cde.*/,"\\1", "g",$0);}' file.txt > outfile.txt 

    Questa è la stessa idea di base di perl e sed , ma utilizzando la funzionalità gang () di gawk.

Vuoi usare un'espressione regolare per questo. Non sono esperta con UNIX regex ma qualcosa di simile dovrebbe funzionare

grep -Po '(?<=abc ).*(?= cde)' test.txt > output.txt

Modifica: l'errore di syntax è venuto da citazioni mancanti, sebbene il vecchio suggerimento non funzionasse piuttosto che desideri utilizzare (?<=xxx) questo è chiamato un'asserzione di look-behind di width zero e senza che tu faccia uno sguardo in avanti. -P per triggersre la perl style regex e -o per printingre solo le partite.

Prova questo e funziona bene con un file di text contenente abc mymatch cde .