Ich habe ein Skript zum Bereinigen von Datendateien
Der Befehl:
for i in `find /ddomain/data/shop12/ -mtime +15 -print|grep -v "^.$" |grep data-`
Ich habe versucht, den Befehl ohne die grep -v
Funktion auszuführen, und sehe keinen Unterschied.
Ich würde gerne wissen, was das grep -v "^.$"
macht. Ich habe dieses Skript nicht erstellt und kann online nichts finden.
Antwort1
grep -v "^.$"
druckt alle Zeilen der Eingabe außer denen, die nur ein einzelnes Zeichen enthalten.
Wie es verwendet wird in:
find /ddomain/data/shop12/ -mtime +15 -print|grep -v "^.$"
wir können davon ausgehen, dass das aktuelle Arbeitsverzeichnis ( .
) aus find
der Ausgabe von verworfen werden soll (wird angezeigt, wenn ein relativer Pfad .
verwendet wird), was problemlos mit einer Option erreicht werden kann -mindepth 1
, obwohl es hier überflüssig ist, da Sie den absoluten Pfad in verwenden find
.
Später suchen Sie nur noch nach Dateien mit data-
im Namen grep data-
, auch das ist redundant. Sie können die gesamte Logik in einem einzigen find
Aufruf zusammenfassen:
find /ddomain/data/shop12/ -name '*data-*' -mtime +15 -print
Auch löschen -print
, das ist die Standardaktion:
find /ddomain/data/shop12/ -name '*data-*' -mtime +15
Hinweis: Wenn Sie nur nach Dateien suchen, fügen Sie -type f
außerdem Folgendes hinzu:
find /ddomain/data/shop12/ -type f -name '*data-*' -mtime +15
Antwort2
Wie andere bereits gesagt haben, grep -v '^.$'
filtert es Zeilen heraus, die aus genau einem Zeichen bestehen (Zeilen, die aus dem Zeilenanfang ( ^
) gefolgt von einem Zeichen ( .
) gefolgt vom Zeilenende ( ) bestehen $
). Eine andere Schreibweise wäre, grep -vx .
wobei das das und implizit -x
macht (das entspricht der ganzen Zeile).^
$
.
Zur Ausgabe von:
find /ddomain/data/shop12/ -mtime +15 -print
Das macht wenig Sinn, da die Ausgabe dieses find
Befehls normalerweise aus Zeilen wie diesen besteht:
/ddomain/data/shop12/foo
/ddomain/data/shop12/foo/bar
...
Die einzige Möglichkeit, dass die Ausgabe Zeilen mit einem einzelnen Zeichen enthält, besteht darin, dass eine Datei mit einem Namen wie folgt vorhanden ist foo<newline>X<newline>
: Das ist durchaus möglich, aber ich würde sagen, dass dies wahrscheinlich nicht die Absicht dieses Befehls war.
Möglicherweise wurde dieser Befehl (fälschlicherweise) von folgendem übernommen:
find . -mtime +15 -print | grep -v '^.$' | grep data-
Wobei das dazu grep
gedacht war, den Eintrag herauszufiltern .
(selbst dann grep -Fvx .
wäre es angemessener gewesen). Dann hätte es allerdings mehr Sinn gemacht, es zu schreiben:
find . ! -name . -path '*data-*' -mtime +15
Wenn Sie das oberste Verzeichnis mit herausfiltern möchten find /ddomain/data/shop12/
, gehen Sie folgendermaßen vor:
find /ddomain/data/shop12/. ! -name . -path '*data-*' -mtime +15
Oder wenn Ihre find
Implementierung das -mindepth
Prädikat unterstützt:
find /ddomain/data/shop12/ -mindepth 1 -path '*data-*' -mtime +15
Antwort3
Dadurch wird das .
Verzeichnis aus der Ergebnisliste entfernt find
. Dies lässt sich anhand eines Beispiels einfacher erklären:
find . -print
.
./prova2
./prova2/prova2
find . -print | grep -v '^.$'
./prova2
./prova2/prova2
Wie Sie sehen, finden wir im ersten Codeausschnitt das .
Ergebnis. Sie übergeben es also an die vom for
Zyklus ausgeführten Aktionen.
Im zweiten Codeausschnitt entscheiden Sie sich, das .
Verzeichnis aus den Ergebnissen von zu überspringen find
, damit Sie es nicht an den for
Zyklus senden.
Antwort4
grep -v '^.$'
schließt Zeilen mit nur einem Zeichen aus.
Beispiel:
echo "foo
> bar
> x" | grep -v '^.$'
foo
bar