2013-07-31 15 views
6

ich eine Daten haben, die wie folgt aussieht (lassen Sie uns diese Datei aufrufen submit.txt):regex Erfassung durchführen und dann ersetzen mit SED/PERL

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

Was möchte ich tun, ist eine Inline-Datei regex Änderung auszuführen damit ergibt sich folgendes

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 

Gibt es einen SED/Perl One Liner dafür?

Meine Schwierigkeit besteht darin, den Namen der Eingabedatei zu erfassen und dann die Ausgabedatei (.output) - für jede Zeile - basierend darauf zu erstellen. Ich bin fest mit diesem:

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

'awk '{print" xxx/x/y/"$ 0"> xxxxxxxx/$ 0}' Liste> output'? Viel Glück. – shellter

+0

Nein, das wird nicht tun. Der Punkt ist für jede Zeile erfassen die 'pmid_xxx 'from' pmid_xxx.txt' und drucke die Ausgabeversion von 'pmid_xxx.output' auch für jede Zeile. – neversaint

+0

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

Antwort

12

Sie können entkommen Klammern verwenden, um Gruppen zu erfassen, und greifen Sie auf die Gruppen mit \ 1, \ 2 usw.

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

Ausgang:

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 

edit: es sieht nicht aus wie sed hat eine eingebaute Dateibearbeitung (GNU sed hat die Option -i). Es ist immer noch möglich zu tun, aber diese Lösung druckt nur nach Standard aus. Sie können auch einen Perl-Liner verwenden, wie hier gezeigt: sed edit file in place

+0

Vielen Dank BTW gibt es eine Möglichkeit, dass ich Ihren Code in mehrere Zeilen aufteilen kann, es ist einfacher, in meinem Editor zu lesen, später erkannte ich. – neversaint

+1

Gern geschehen! Sie könnten Shell-Variablen verwenden, um es zu teilen ähnlich wie folgt: http://stackoverflow.com/questions/8078872/can-a-long-sed-command-be-broken-over-several-lines Speichern Sie die Suchzeichenfolge grundsätzlich in einer Variablen und ersetzen Sie die Zeichenfolge in einem anderen. Ich weiß nicht, ob das viel helfen würde, da die Ersetzungszeichenfolge sti Ich werde ziemlich lang sein. Sie könnten den Such- und Ersetzungsteil auch in eine Datei einfügen und sie mit der Option sed -f aufrufen – chilemagic

1

Sie haben nach einem Sed-Liner gefragt, Sie haben ihn bekommen.

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

+0

Verwenden Sie ein anderes Trennzeichen anstelle von /, wenn Sie viele Schrägstriche in der Zeichenfolge haben (z. B. Dateinamen). Sed arbeitet auch mit _, | oder :. –

0

Das Perl oneliner für das gleiche zu tun ist

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

Der obige Befehl wird einen ersetzt String in der Konsole produzieren, und Sie haben die Ausgabe in einer anderen Datei zu umleiten.

Zum Ersetzen innerhalb der Datei (Inline Replace) können Sie die Option -i hinzufügen. Für zB

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

Die oben wird ein Ersatz innerhalb der submit.txt Datei selbst ausführen.