2012-05-15 16 views
6

Al meine HTML-Dateien befinden sich hier:Wie kopiert man die Top 10 der letzten Dateien von einem Verzeichnis in ein anderes?

/home/thinkcode/myfiles/html/ 

ich die neuesten 10 Dateien /home/thinkcode/Test

Ich habe dies so weit verschieben möchten. Bitte korrigieren Sie mich. Ich bin auf der Suche nach einem One-Liner!

ls -lt *.htm | head -10 | awk '{print "cp "$1" "..\Test\$1}' | sh 
+3

Sie könnten 'xargs' verwenden und' awk' + 'sh' vermeiden (fühlt sich hässlich an) oder wahrscheinlich' find ... -exec' verwenden und nur einen Befehl ausführen. – KurzedMetal

+0

Ich könnte den Fund machen, aber ich habe mich nur gefragt, wie man das Gleiche mit awk macht! – ThinkCode

+3

Siehe [BashFAQ/003] (http://mywiki.wooledge.org/BashFAQ/003) und [BashFAQ/099] (http://mywiki.wooledge.org/BashFAQ/099). –

Antwort

9
ls -lt *.htm | head -10 | awk '{print "cp " $9 " ../Test/"$9}' | sh 
+5

'ls' ist notorisch schlecht beim Auflisten von Dateinamen, die Sonderzeichen enthalten. Auch das Parsen der Ausgabe von "ls-l" ist mit Gefahren behaftet. Es ist besser, ein kleines Perl-Skript zu schreiben, das alle Dateien ausgibt und die Ergebnisse nach Datum sortiert. Wenn Sie 'ls' verwenden müssen, lassen Sie mindestens das Argument' -l' aus: 'ls -t * .html | Kopf -10' würde genauso gut funktionieren. –

4
ls -lt *.html | head -10 | awk '{print $NF}' | xargs -i cp {} DestDir 

Im obigen Beispiel DestDir ist das Zielverzeichnis für die Kopie.

Fügen Sie nach xargs -t hinzu, um die Befehle bei ihrer Ausführung anzuzeigen. I.e., xargs -i -t cp {} DestDir.

Weitere Informationen finden Sie in der xargs command.

EDIT: Wie @DennisWilliamson hingewiesen (und auch die aktuelle Manpage Prüfung) erneut die -i Option This option is deprecated; use -I instead..

Auch beide dargestellten Lösungen hängen von den Dateinamen in Fragen enthalten keine Leerzeichen oder Tabs.

+0

Wie kopiert man die Dateien in das Verzeichnis ../test? – ThinkCode

+0

ls -lt * .htm | Kopf -10 | awk '{print $ NF}' | xargs cp * ../Test/? Funktioniert nicht. Wie sammle ich die Dateinamen aus der Pipe und füttere den Kopierbefehl? – ThinkCode

+0

es ist '{}', nicht '*' –

6

Hier ist eine Version, die ls nicht verwendet. Es sollte weniger anfällig für seltsame Zeichen in Dateinamen:

find . -maxdepth 1 -type f -name '*.html' -print0 
    \| xargs -0 stat --printf "%Y\t%n\n" 
    \| sort -n 
    \| tail -n 10 
    \| cut -f 2 
    \| xargs cp -t ../Test/ 

I verwendet find für ein paar Gründe:

1), wenn es zu viele Dateien in einem Verzeichnis sind, sträuben bash wird am Wildcard Erweiterung*.

2) Mit dem -print0 Argument zu find wird das Problem der Bash erweitern Whitespace in einem Dateinamen in mehrere Token.

* Tatsächlich teilt bash einen Speicherpuffer für seine Wildcard-Erweiterung und seine Umgebungsvariablen, also ist es nicht streng eine Funktion der Anzahl der Dateinamen, sondern die Gesamtlänge der Dateinamen und Umgebungsvariablen. Zu viele Umgebungsvariablen => keine Wildcard-Erweiterung.

BEARBEITEN: Incorporated einige Verbesserungen von @ Glennjackman. Die ursprüngliche Verwendung von find wurde beibehalten, um die Verwendung der Platzhaltererweiterung zu vermeiden, die in einem großen Verzeichnis fehlschlagen könnte.

+3

+1 für nicht mit ls. Kann etwas einfacher sein: 'stat -c"% Y \ t% n "* .html | sortieren -n | Schwanz -10 | geschnitten -d "" -f 2- | xargs cp -t ../ Test' –

+0

@glennjackman: ist der Schnitt bei Tab-Zeichen, die als "" gedruckt, wenn Sie eingefügt? – ToolmakerSteve

+0

Guter Punkt. Es sollte "cut -d $ '\ t' ..." sein. –

Verwandte Themen