2010-06-10 10 views
13

Ich habe eine ganze Reihe von Dateien in einem Verzeichnis und von jeder Datei möchte ich die erste Zeile entfernen (einschließlich Wagenrücklauf). Ich kann die ganze Datei in ein Array von Strings lesen und alle außer dem ersten Element in eine neue Datei schreiben, aber das sieht für mich etwas umständlich aus, gibt es bessere Möglichkeiten? Oh, die bevorzugte Sprache ist Perl.Perl: Wie entferne ich die erste Zeile einer Datei, ohne ganze Datei zu lesen und zu kopieren

+10

Dies ist unmöglich, weil Dateien gespeichert sind. Sie müssen immer die gesamte Datei lesen und alles außer der ersten Zeile schreiben - das OS hat keine andere Möglichkeit. – Konerak

Antwort

23

Versuchen Sie diesen Einzeiler

perl -pi -e '$_ = "" if ($. == 1);' filename 

ich es vorher verwendet haben, sollte alles, was Sie sein müssen.

+0

+1 Niemals mehr als eine Zeile gleichzeitig speichern. – mob

+0

Können Sie erklären, wie das funktioniert? – FistOfFury

+0

im Grunde sagt es run Perl, Parse an Ort und Stelle die folgende Codezeile aus. Die folgende Zeile verwendet die Standardvariable $ _, die in diesem Fall die durch die Option -p eingelesene Zeile ist. $. ist die Zeilennummer des Dateinamens. Wenn also die Zeilennummer == 1 ist, dann setze den Text der Zeile auf "". –

5
use Tie::File qw(); 
for my $filename (glob 'some_where/some_files*') { 
    tie my @file, 'Tie::File', $filename or die "Could not open $filename: $!"; 
    shift @file; 
} 
+0

+1 wenn nur für deine PS. :) –

+1

Beachten Sie, dass dies immer noch die gesamte Datei lesen und kopieren muss, aber das ist inhärent in dem Problem. Ich kenne kein Betriebssystem, das eine andere Möglichkeit bietet, Daten vom Anfang einer Datei zu entfernen. – cjm

+0

Krawatte :: Datei ist meine offensichtliche Wahl, weil es ausdrücklich geschrieben wurde, um mit genau dieser Problemkategorie effizient umzugehen. – daxim

9
perl -n -i -e 'print unless $. == 1' myfile 

Dies ist ähnlich der Antwort von Stocherilac.

Aber in jedem Fall (und in allen anderen Antworten gegeben!) Sie lesen immer die vollständige Datei. Keine Möglichkeit, das zu vermeiden, AFAIK.

+0

+1 für mehr als eine Möglichkeit, es zu tun :) –

+0

+1 für eine (IMHO) besser lesbare Version. –

+0

In Windows unter MinGW Konsole löschte ich meine Datei "Kann Inplace nicht bearbeiten auf Myfile: Berechtigung verweigert" – user869097

11

Wie wäre es

tail +2 

in der Schale?

(edit: in neueren Linux können Sie benötigen tail -n +2 (danke, GNU :()!)

9

Oh die gewünschte Sprache ist Perl

Manchmal sed ein sed besser als. sogar perl:

sed -i 1d * 
-1

Wie Schwern wies darauf hin, hat die folgende nicht einen frühzeitigen Ausstieg durchführen, wie ich ursprünglich gedacht hatte, es würde:

perl -pi -e '$_ = q// and last if $. == 1;' myFile 

Scheint wie ein kann nicht vermeiden Verarbeitung der gesamten Datei, nachdem alle.

+4

Dies tut nicht, was Sie denken, dass es tut. Wenn dies der Fall wäre, würde dies die Funktionsweise von Dateien unter Unix verletzen. Was wirklich passiert, ist '$ _ =" "' ist immer falsch, also ist '$ _ =" "und" last "dasselbe wie" 0 and last ".Es schließt kurz und ruft niemals 'last'. Sie haben geschrieben: 'perl -pi e '$ _ = q // if $. == 1 'myFile' ist eine clevere Möglichkeit, die erste Zeile nicht zu drucken, liest aber auf jeden Fall die ganze Datei. Führen Sie mit "-MO = Deparse" aus, um den Code abzurufen und im Debugger auszuführen. 'tu {dies; Das; } wenn etwas ein sichereres Konstrukt ist. – Schwern

+0

@Schwern: Mein schlechtes. Es hat eine Weile gedauert, bis deine Erklärung unterging, aber ich verstehe deinen Standpunkt. – Zaid

Verwandte Themen