Immer nur die neueste Datei kopieren

Probleme mit Samba, NFS, FTP und Co.
Antworten
katze123
Beiträge: 88
Registriert: 10.06.2016 20:05:47

Immer nur die neueste Datei kopieren

Beitrag von katze123 » 01.06.2017 21:50:55

Ich habe einen Ordner mit vielen Dateien und möchte, dass die neueste (die mit dem jüngsten Änderungsdatum) per Shellskript in einen bestimmten Zielordner kopiert wird. Die restlichen Dateien sollen weggelassen werden. Wie setz ich das in die Tat um?

Benutzeravatar
whisper
Beiträge: 3182
Registriert: 23.09.2002 14:32:21
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Re: Immer nur die neueste Datei kopieren

Beitrag von whisper » 01.06.2017 22:14:39

Aus dem Stehgreif, ungetestet:

Code: Alles auswählen

ls -tr|tail -1
oder

Code: Alles auswählen

ls -t|head -1
Rest bekommst du hin?

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Immer nur die neueste Datei kopieren

Beitrag von Meillo » 01.06.2017 23:45:13

whisper hat geschrieben:Aus dem Stehgreif, ungetestet:

Code: Alles auswählen

ls -tr|tail -1
oder

Code: Alles auswählen

ls -t|head -1
Nimm zweiteren Ansatz, weil der nur eine Zeile durch die Pipe schieben muss, waehrend bei ersterem alles durchgeschoben aber bis auf die letzte Zeile verworfen wird.

`head -1' und `tail -1' sind nicht (mehr) POSIX-kompatibel. Schreibe daher: `head -n 1' bzw. `tail -n 1'.

`head -n 17' kann immer durch `sed 17q' ersetzt werden. `head -n 1' sogar durch `sed q'. ... fuer den Fall, dass du gerne mehr unixy sein willst. ;-)
Use ed once in a while!

katze123
Beiträge: 88
Registriert: 10.06.2016 20:05:47

Re: Immer nur die neueste Datei kopieren

Beitrag von katze123 » 02.06.2017 00:06:11

Danke für eure Antworten, ls -t|head -1 funktioniert wunderbar.

breakthewall
Beiträge: 507
Registriert: 30.12.2016 23:48:51

Re: Immer nur die neueste Datei kopieren

Beitrag von breakthewall » 04.06.2017 07:46:23

Generell ist es überhaupt nicht sicher noch ratsam den Output von ls zu parsen, aufgrund vielfacher Fallstricke bezüglich Datei -und Ordnernamen.

Daher eine Lösung mit find:

Code: Alles auswählen

find . -maxdepth 1 -type f -printf "%T@ %p\n" | sort -n | tail -n 1 | cut -d ' ' -f 2-

uname
Beiträge: 12072
Registriert: 03.06.2008 09:33:02

Re: Immer nur die neueste Datei kopieren

Beitrag von uname » 04.06.2017 09:22:41

Vielleicht auch so:

Code: Alles auswählen

find . -maxdepth 1 -type f -printf "%T@ %p\n"|awk '{if ($1>a){a=$1;b=$2}} END {print b}'
Nachtrag Punkt-Dateien:
Bei "ls" werden Punktdateien ignoriert. Du musst "ls -a" verwenden, um die "versteckten" Dateien einzubeziehen.

Bei dem find-Befehl sind sie standardmäßig enthalten. Um sie auszuschließen verwende:

Code: Alles auswählen

find . -maxdepth 1 -not -path '*/\.*' -type f -printf "%T@ %p\n"|awk '{if ($1>a){a=$1;b=$2}} END {print b}'

Benutzeravatar
whisper
Beiträge: 3182
Registriert: 23.09.2002 14:32:21
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Re: Immer nur die neueste Datei kopieren

Beitrag von whisper » 04.06.2017 10:06:10

Meillo hat geschrieben:
whisper hat geschrieben:Aus dem Stehgreif, ungetestet:

Code: Alles auswählen

ls -tr|tail -1
oder

Code: Alles auswählen

ls -t|head -1
`head -1' und `tail -1' sind nicht (mehr) POSIX-kompatibel. Schreibe daher: `head -n 1' bzw. `tail -n 1'.

`head -n 17' kann immer durch `sed 17q' ersetzt werden. `head -n 1' sogar durch `sed q'. ... fuer den Fall, dass du gerne mehr unixy sein willst. ;-)
Aha, ja immer diese Neuerungen.
Aber meinen Dank an dich für die Alternativen!

Benutzeravatar
whisper
Beiträge: 3182
Registriert: 23.09.2002 14:32:21
Lizenz eigener Beiträge: GNU Free Documentation License
Kontaktdaten:

Re: Immer nur die neueste Datei kopieren

Beitrag von whisper » 04.06.2017 10:09:22

katze123 hat geschrieben:Danke für eure Antworten, ls -t|head -1 funktioniert wunderbar.
Die anderen Lösungen sind natürlich auch richtig und besser, mein Ansatz war: User am Anfang der Scriptingkariere; nicht überfordern mit komplexeren als notwendigen Alternativen.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Immer nur die neueste Datei kopieren

Beitrag von Meillo » 08.06.2017 22:35:54

breakthewall hat geschrieben:Generell ist es überhaupt nicht sicher noch ratsam den Output von ls zu parsen, aufgrund vielfacher Fallstricke bezüglich Datei -und Ordnernamen.
Welche denn (die sich nicht auf `ls -l' beziehen)? Hast du dazu irgendwelche Referenzen?

Falls du auf Newlines in Dateinamen anspielen solltest, dann macht das deine Pipeline auch nicht besser.
Use ed once in a while!

breakthewall
Beiträge: 507
Registriert: 30.12.2016 23:48:51

Re: Immer nur die neueste Datei kopieren

Beitrag von breakthewall » 09.06.2017 20:16:30

Meillo hat geschrieben:Welche denn (die sich nicht auf `ls -l' beziehen)? Hast du dazu irgendwelche Referenzen?
http://mywiki.wooledge.org/ParsingLs
https://unix.stackexchange.com/question ... t-parse-ls
Meillo hat geschrieben:Falls du auf Newlines in Dateinamen anspielen solltest, dann macht das deine Pipeline auch nicht besser.
Doch tut sie. Denn für find spielt das alles keine Rolle, egal wie komplex oder exotisch der Input auch ist, da find selbst ist nicht diesen Problemen unterworfen ist. Da können Datei -und Ordnernamen auch Tabs, Spaces, Newlines und sonstigen Käse enthalten, selbst exotische Sonderzeichen, dass wird immer sauber aufgelistet und verarbeitet ohne dubiose Endergebnisse. Generell sollte man immer Shell-Globbing nutzen für Datei -und Ordnernamen, ganz egal um was es auch geht, oder universelle Programme wie find, die schon darauf getrimmt sind jeden Mist zu verarbeiten und kompatibel weiterzureichen. Und hier ist das Problem da insbesondere ls nicht garantieren kann, dass das was aufgelistet wird auch das ist was wirklich existiert und entsprechend weitergegeben wird. Das hängt stark vom Input ab, da ls nur ein sehr einfaches Programm ist und nicht für so etwas geschaffen wurde. Da muss man sehr aufpassen, gerade weil die Shell ein Interpreter ist, und das sehr abenteuerliche Folgen haben kann. Von daher sollte man lieber Lösungen nutzen, die auch Daten auf sichere Weise verarbeiten. Und da sind Programme wie find nun mal etwas ganz Feines. Man könnte natürlich auch gleich Python nutzen, und erschlägt damit all diese Probleme.

Benutzeravatar
Meillo
Moderator
Beiträge: 8813
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Immer nur die neueste Datei kopieren

Beitrag von Meillo » 09.06.2017 21:18:11

breakthewall hat geschrieben:
Meillo hat geschrieben:Welche denn (die sich nicht auf `ls -l' beziehen)? Hast du dazu irgendwelche Referenzen?
http://mywiki.wooledge.org/ParsingLs
https://unix.stackexchange.com/question ... t-parse-ls
Danke, die sehen interessant und fundiert aus. Ich lese mir die gerne in Ruhe durch.

Meillo hat geschrieben:Falls du auf Newlines in Dateinamen anspielen solltest, dann macht das deine Pipeline auch nicht besser.
Doch tut sie.
Dann lege mal eine Datei mit Newline an und fuehre darauf deine find-Pipieline und die ls-Pipepine aus. Du wirst sehen, dass beide in gleicher Weise scheitern. ;-)

Alleine find(1) zu verwenden loest *nicht* einfach das Problem! Find(1) kann lediglich helfen manche Problem zu loesen, die man mit ls(1) nicht loesen kann.
Denn für find spielt das alles keine Rolle, egal wie komplex oder exotisch der Input auch ist, da find selbst ist nicht diesen Problemen unterworfen ist. Da können Datei -und Ordnernamen auch Tabs, Spaces, Newlines und sonstigen Käse enthalten, selbst exotische Sonderzeichen, dass wird immer sauber aufgelistet und verarbeitet ohne dubiose Endergebnisse.
Ich verstehe natuerlich schon was du meinst: Die internen Tests von find(1) funktionieren korrekt in all diesen Faellen. Aber sobald du die find-Ausgaben in eine Pipe schiebst, dann ist das Ergebnis gleich wie wenn die die Ausgaben von ls(1) in eine Pipe schiebst. Und die interne Funktion `-t' von ls(1) funktioniert halt ebenso korrekt wie die internen Funktionen von find(1).

Nur mit `-print0' kannst du korrekt durch die Pipe kommen und das bietet zwar find(1) aber nicht ls(1). Aber das verwendest du in deiner Pipeline ja gar nicht ... weil es natuerlich alle Tools in der Pipeline unterstuetzen muessten, was halt nicht der Fall ist.

[...] da ls nur ein sehr einfaches Programm ist und nicht für so etwas geschaffen wurde.
Fuer was wurde ls(1) nicht geschaffen? Dateien aufzulisten? Ha, *gerade* dafuer wurde es geschaffen und das kann es in perfekter Weise. Das Problem ist nicht ls(1), sondern dass man Newlines in Dateinamen hat. Es ist IMO eine der wenigen schlechten Entscheidungen der Unix-Entwickler gewesen, Newlines in Dateinamen zu erlauben, weil das seither einen ganzen Rattenschwanz an Haesslichkeiten hervorgebracht hat, ohne, dass man von den Newlines in Dateinamen irgendeinen Nutzen haette. Meine Meinung ist, dass man Scripte fuer diesen Fall nicht verkomplizieren sollte (dazu fuehrt es naemlich: zu einer Halbierung der Lesbarkeit der Scripte), weil Unix-Systeme keine Newlines in Dateinamen haben sollten, und wer sowas hat, soll selber schauen wie er damit zurecht kommt. Das ist halt meine Meinung ... die aber nur am Rande, denn oben Geschriebenes ist davon unabhaengig und sachlich.

Ich will nochmal unterstreichen, das Problem ist nicht ls(1). Deine Aussage ist mir zu pauschal und deine Loesung bietet eben nicht das Versprochene sondern bloss das Gleiche wie mit ls(1) in weniger lesbar. Nichts desto trotz schaetze ich deine Anmerkung in diesem Thread, denn es ist wichtig, sich mit solchen Fragen zu befassen.
Use ed once in a while!

Antworten