2013-07-31 16 views
6

Ho un dato che assomiglia a questo (chiamiamolo questo file submit.txt):Esecuzione di cattura regex e poi sostituirlo con SED/PERL

dir1/pmid_5409464.txt 
dir1/pmid_5788247.txt 
dir1/pmid_4971884.txt 

Quello che voglio fare è quello di eseguire un cambiamento regex file di inline in modo che risulti il ​​seguente

perl mycode.pl /home/neversaint/dir1/pmid_5409464.txt > /home/neversaint/dir1/pmid_5409464.output 
perl mycode.pl/home/neversaint/dir1/pmid_5788247.txt > /home/neversaint/dir1/pmid_5788247.output 
perl mycode.pl /home/neversaint/dir1/pmid_4971884.txt > /home/neversaint/dir1/pmid_4971884.output 

C'è un rivestimento SED/Perl per farlo?

La mia difficoltà è nel catturare il nome del file di input e quindi creare il file di output (.output) - per ogni riga - basato su quello. Sono bloccato con questo:

sed 's/^/perl mycode.pl \/home\/neversaint\/dir1\//g' submit.txt | 
sed 's/$/ >/' 
+1

'awk '{stampa" xxx/x/y/"$ 0"> xxxxxxxx/$ 0}' lista> output'? Buona fortuna – shellter

+0

No, non lo farò. Il punto è per ogni riga che cattura il 'pmid_xxx 'da' pmid_xxx.txt' e stampiamo la versione di output di quel 'pmid_xxx.output' anche per ogni riga. – neversaint

+0

sed http://stackoverflow.com/questions/2777579/how-to-output-only-captured-groups- with-sed –

risposta

12

è possibile utilizzare parentesi sfuggito per catturare gruppi, e accedere ai gruppi con \ 1, \ 2, ecc

sed 's/^\(.*\).txt$/perl mycode.pl \/home\/neversaint\/\1\.txt > \/home\/neversaint\/\1.output/' submit.sh 

uscita:

perl mycode.pl /home/neversaint/dir1/pmid_5409464.txt > /home/neversaint/dir1/pmid_5409464.output 
perl mycode.pl /home/neversaint/dir1/pmid_5788247.txt > /home/neversaint/dir1/pmid_5788247.output 
perl mycode.pl /home/neversaint/dir1/pmid_4971884.txt > /home/neversaint/dir1/pmid_4971884.output 

modifica: non sembra che sed abbia un editing di file sul posto (GNU sed ha l'opzione -i). È ancora possibile farlo, ma questa soluzione si limita a standardizzare. Potresti anche usare un rivestimento Perl one come mostrato qui: sed edit file in place

+0

grazie mille.BBW c'è un modo per dividere il tuo codice in più righe: è più facile leggerlo in questo modo nel mio editor, più tardi mi sono reso conto – neversaint

+1

Sei il benvenuto! Puoi usare le variabili di shell per dividerlo in alto, in questo modo: http://stackoverflow.com/questions/8078872/can-a-long-sed-command-be-broken-over-several-lines. In pratica memorizza la stringa di ricerca in una variabile e sostituisce la stringa in un altro, non so se questo sarebbe di grande aiuto dato che la stringa di sostituzione sarebbe sti Sarò piuttosto lungo. Puoi anche inserire la ricerca e sostituire parte in un file e chiamarla usando l'opzione sed -f – chilemagic

1

Hai chiesto una copertina di Sed, ce l'hai.

sed 's/\([^.]*\)\.txt/perl mycode.pl \/home\/neversaint\/\1.txt > \/home\/neversaint\/\1.output/' submit.txt > output.txt

+0

Usa un altro separatore, invece di /, quando hai molte barre nella stringa (ad esempio nomi di file). Sed funziona anche con _, | o :. –

0

L'oneliner perl per fare lo stesso è

perl -pe "[email protected](.*?)(\.txt)@perl mycode.pl /home/neversaint/\\1\\2 > /home/neversaint/\\[email protected]" submit.txt 

Il comando precedente produrrà una stringa sostituito nella console e si deve reindirizzare l'output in un altro file.

Per la sostituzione all'interno del file (sostituzione in linea) è possibile aggiungere l'opzione -i. Per esempio

perl -pe "[email protected](.*?)(.txt)@perl mycode.pl /home/neversaint/\1\2 > /home/neversaint/\[email protected]" -i submit.txt 

Quanto sopra eseguirà una sostituzione all'interno del file submit.txt stessa.

Problemi correlati