Wie kann ich rekursiv alle Dateien bzip2, die nicht bzipped sind?

7

Wie kann ich rekursiv alle Dateien bzip2, die unter .bz2Linux nicht mit der Erweiterung enden ?

Alon Gubkin
quelle

Antworten:

8

find ist dein Freund. Ich denke, das sollte es tun:

find <target_dir> -not -name \*.bz2 -exec bzip2 \{\} \;

dh wenn das Verzeichnis, in dem sich die Dateien befinden, die Sie bzipen möchten, / var / log / blah ist, wäre dies:

find /var/log/blah -not -name \*.bz2 -exec bzip2 \{\} \;
Jason Tan
quelle
1
Es kann schneller zu bedienen sein +oder xargsstatt \;. Es ist nicht notwendig, den geschweiften Klammern zu entkommen. POSIX unterstützt !"nicht".
Bis auf weiteres angehalten.
Warum abstimmen? Funktioniert es nicht auf der angegebenen Plattform?
Jason Tan
Keine Ahnung warum die Ablehnung, dies ist die beste (und richtige) Antwort, ich benutze sie die ganze Zeit. Ich benutze aber auch xargs, kann es nicht ertragen, die -exec zu finden. Verwenden Sie auch -print0 für die Suche und -0 für xargs, um die NULL-Trennung anstelle von Leerzeichen zu verwenden, falls die Dateinamen Leerzeichen enthalten.
1
Wenn es sich nicht nur um sehr kleine Dateien handelt, ist xargs wahrscheinlich sowieso eine vorzeitige Optimierung (die eigentliche Komprimierung wird die meiste Zeit in Anspruch nehmen, nicht die Verzweigung und Ausführung des wiederholten Starts von bzip2) ... Aber:find /var/log/blah -not -name \*.bz2 -print0 | xargs -0 bzip2
freiheit
1

Auf den ersten Blick (Entschuldigung, ich habe keine Shell zum Testen von Zitaten usw. zur Hand):

for _t in `find . -print |grep -v -E "\.bz$"`; do bzip2 -9 $_t && echo OK $_t || echo FAIL $_t; done

Dies verwendet find, um alle Dateien zu finden, grep, um diejenigen mit der Erweiterung .bz2 zu entfernen und sie dann einzeln in bzip2 einzuspeisen. Ich gehe jedoch davon aus, dass ein Teil des Zitats falsch ist - ich würde das Bit in den Backquotes zuerst separat testen.

Viel Glück! Vielleicht möchten Sie stattdessen xz verwenden - es wird normalerweise besser komprimiert - oder sogar alles tarieren und stattdessen bzip2 oder xz.

Rup
quelle
... oder anscheinend kannst du alles in find machen. Ich wusste nicht, dass es '-nicht' kann, daher der Grep usw. hier.
Rup
Ich denke, das -not in find ist nur eine GNU-Suchoption - daher glaube ich nicht, dass Sie es mit den meisten proprietären Suchbefehlen verwenden könnten - aber da die Frage Linux angibt, ist GNU find wahrscheinlich in Ordnung - Ihr Ansatz ist wahrscheinlich portabler.
Jason Tan
POSIX unterstützt !"nicht". Die Verwendung einer forSchleife schlägt für Dateien fehl, deren Namen Leerzeichen enthalten. Sie sollten verwenden find | while read.
Bis auf weiteres angehalten.
1

Mit zsh ( setopt extended_globmuss eingeschaltet sein):

bzip2 **/^*.bz2(.)

**Rekursionen in Unterverzeichnissen; ^*.bz2passt zu allem außer *.bz2; (.)beschränkt sich auf reguläre Dateien.

Wenn Sie mit Bash 4 die bzip2Beschwerden über das Aufrufen von Verzeichnissen ignorieren können :

bzip2 **/!(*.bz2)
Gilles 'SO - hör auf böse zu sein'
quelle
0

Hier ist ein Einzeiler. Falls erforderlich, ifnezuerst installieren . Unter Ubuntu:

sudo apt-get install moreutils

Und dann:

find YOUR_DIR -type f -not -name \*.bz2 -print0 | ifne xargs -0 bzip2

Dies funktioniert genauso wie bei anderen Antworten, es werden jedoch keine Warnmeldungen zu bzip2ing-Verzeichnissen angezeigt. Wenn nichts bzip2mehr zu tun ist, werden keine Warnmeldungen zu bzip2-komprimierten Daten an ein Terminal gesendet. Es verwendet auch xargsetc.

YOUR_DIR kann Platzhalter oder mehrere Verzeichnisse haben, z. B. YOUR * DIR oder ähnliches.

Plätzchen
quelle
0

In der fishKonsole ist es ziemlich einfach und Sie müssen sich keine Gedanken über Rohre und seltsame Backslashes machen:

set files (find *)
for i in $files
    bzip2 $i
end
user258532
quelle