Wie können mit dem ls-Befehl und den Optionen die sich wiederholenden Dateinamen in verschiedenen Verzeichnissen aufgelistet werden?Wie klassifiziere ich Dateien auf Linux-Servern nach ihren Namen?
Antwort
Sie können dazu keinen einfachen Basisbefehl ls
verwenden. Sie müssten eine Kombination aus anderen POSIX/Unix/GNU-Dienstprogrammen verwenden. Um zum Beispiel der doppelten Dateinamen finden zuerst:
find . -type f -exec basename "\{}" \; | sort | uniq -d > dupes
Das bedeutet find
alle Dateien (-type f
) durch die gesamte Verzeichnishierarchie im aktuellen Verzeichnis (.
) und Ausführen (-exec
) den Befehl basename
(der Streifen der Verzeichnisteil) für die gefundene Datei (\{}
), Ende des Befehls (\;
). Diese Dateien sortieren und drucken dann doppelte Zeilen (uniq -d
). Das Ergebnis geht in die Datei dupes
. Jetzt haben Sie die Dateinamen, die dupliziert sind, aber Sie wissen nicht, in welchem Verzeichnis sie sich befinden. Verwenden Sie erneut find
, um sie zu finden. Verwendung bash
als Shell:
while read filename; do find . -name "$filename" -print; done < dupes
Dies bedeutet Schleife durch (while
), um alle Inhalte der Datei dupes
read
und in die Variable filename
jeder Zeile. Führen Sie für jede Zeile erneut find
aus und suchen Sie nach dem spezifischen -name
der $filename
und drucken Sie es aus (-print
, aber es ist implizit, so dass dies redundant ist).
Wahrheit zu sagen Sie diese ohne Verwendung einer Zwischendatei kombinieren:
find . -type f -exec basename "\{}" \; | sort | uniq -d | while read filename; do find . -name "$filename" -print; done
Wenn Sie nicht mit ihm vertraut sind, die |
Operator Mittel, führen Sie den folgenden Befehl, um die Ausgabe des vorherigen Befehls als die Eingabe für den folgenden Befehl. Beispiel:
[email protected]:~$ mkdir test
[email protected]:~$ cd test
[email protected]:~/test$ mkdir 1 2 3 4 5
[email protected]:~/test$ mkdir 1/2 2/3
[email protected]:~/test$ touch 1/0000 2/1111 3/2222 4/2222 5/0000 1/2/1111 2/3/4444
[email protected]:~/test$ find . -type f -exec basename "\{}" \; | sort | uniq -d | while read filename; do find . -name "$filename" -print; done
./1/0000
./5/0000
./1/2/1111
./2/1111
./3/2222
./4/2222
Haftungsausschluss: Die Anforderung besagt, dass die Dateinamen alle Zahlen sind. Während ich versucht habe, den Code so zu gestalten, dass er Dateinamen mit Leerzeichen behandelt (und in Tests auf meinem System funktioniert), kann der Code brechen, wenn er auf Sonderzeichen, Zeilenumbrüche, Nullen oder andere ungewöhnliche Situationen stößt. Bitte beachten Sie, dass der Parameter -exec
besondere Sicherheitsaspekte berücksichtigt und nicht von Root über beliebige Benutzerdateien verwendet werden sollte. Das vereinfachte Beispiel dient nur illustrativen und didaktischen Zwecken. Bitte konsultieren Sie Ihre man
Seiten und relevante CERT Advisories für volle Sicherheit.
Berühren Sie eine Datei mit dem Namen "file01 01 17" an mehreren Stellen und versuchen Sie Ihren Code. –
@GeorgeVasiliou, funktioniert für mich, ich habe es versucht. Außerdem zeigte das Plakat an, dass seine Dateinamen alle Nummern waren. Es gab keine Anforderung, Dateinamen mit Leerzeichen zu behandeln, also habe ich den Code für dieses Szenario nicht speziell getestet. Ich füge jedoch einen Haftungsausschluss hinzu. – eewanco
Ich habe eine Funktion in meinem Bash-Profil (bash 4.4) für doppelte Dateien. Es stimmt, dass das Finden das richtige Werkzeug ist.
Ich benutze find kombiniert mit -print0
Optionen, die die Suchergebnisse mit Null-Zeichen anstelle von neuen Zeilen trennt (Standard-Suche Aktion). Jetzt kann ich alle Dateien unter dem aktuellen Verzeichnis und den Unterverzeichnissen abfangen.
Dies stellt sicher, dass die Ergebnisse korrekt sind, egal ob Dateinamen spezielle Zeichen wie Leerzeichen oder neue Zeilen enthalten (in einigen sehr seltenen Fällen). Anstatt doppelt zu suchen, finde ich ein Array und finde nur die doppelten Dateien in diesem Array. Dann grep das ganze Array mit den "Duplikaten" als Muster.
So etwas wie dies für meine Funktion ok funktioniert:
$ IFS= readarray -t -d '' fn< <(find . -name 'file*' -print0)
# find all files and load them in an array using null delimiter
$ printf '%s\n' "${fn[@]}" #print the array
./tmp/file7
./tmp/file14
./tmp/file11
./tmp/file8
./tmp/file9
./tmp/tmp2/file09 99
./tmp/tmp2/file14.txt
./tmp/tmp2/file15.txt
./tmp/tmp2/file$100
./tmp/tmp2/file14.txt.bak
./tmp/tmp2/file15.txt.bak
./tmp/file1
./tmp/file4
./file09 99
./file14
./file$100
./file1
$ dupes=$(LC_ALL=C sort <(printf '\<%s\>$\n' "${fn[@]##*/}") |uniq -d)
#Locate duplicate files
$ echo "$dupes"
\<file$100\>$ #Mind this one with special char $ in filename
\<file09 99\>$ #Mind also this one with spaces
\<file14\>$
\<file1\>$
#I have on purpose enclose the results between \<...\> to force grep later to capture full words and avoid file1 to match file1.txt or file11
$ grep -e "$dupes" <(printf '%s\n' "${fn[@]}") |awk -F/ '{print $NF,"==>",$0}' |LC_ALL=C sort
file$100 ==> ./file$100 #File with special char correctly captured
file$100 ==> ./tmp/tmp2/file$100
file09 99 ==> ./file09 99 #File with spaces in name also correctly captured
file09 99 ==> ./tmp/tmp2/file09 99
file1 ==> ./file1
file1 ==> ./tmp/file1
file14 ==> ./file14 #other files named file14 like file14.txt and file14.txt.bak not captured since they are not duplicates.
file14 ==> ./tmp/file14
Tipps: auf der
Dieser
<(printf '\<%s\>$\n' "${fn[@]##*/}")
verwendet Prozess Substitution$ IFS= readarray -t -d '' fn< <(find . -name 'file*' -print0) $ dupes=$(LC_ALL=C sort <(printf '\<%s\>$\n' "${fn[@]##*/}") |uniq -d) $ grep -e "$dupes" <(printf '%s\n' "${fn[@]}") |awk -F/ '{print $NF,"==>",$0}' |LC_ALL=C sort
Dies ist ein Test Der Basisname des Finds wird mit bash in Parametererweiterungstechniken erstellt.
LC_ALL = C wird beim Sortieren benötigt, damit die Dateinamen korrekt sortiert werden.
In den Bash-Versionen vor 4.4 akzeptiert das Readarray keine Option -d (Delimiter). In diesem Fall können Sie die Ergebnisse in ein Array mit
transformieren, während IFS = read -r-d '' res; tun fn + = ("$ res"); done < < (finden Sie .... -print0)
- 1. Wie kann ich Git Zweige basierend auf ihren Namen färben?
- 2. Wie klassifiziere ich Text mit einem Schätzer?
- 3. Python durchläuft Variablen basierend auf ihren Namen
- 4. Sollten ausführbare Dateien Versionsnummern in ihren Namen enthalten?
- 5. Matlab: Wie öffne ich mehrere .txt-Dateien mit ihren Namen für Variablennamen
- 6. Eingangsvariable in Makefile lesen und Variable auf ihren Namen setzen
- 7. Namen heruntergeladenen Dateien nach bestimmten HTML-Element
- 8. Wie klassifiziere ich das Bild in Echtzeit mit Tensorflow?
- 9. Kann ich .laccdb-Dateien ausblenden oder ändern Sie ihren Namen mit MS Access-Einstellungen
- 10. Wie grep und kopieren Sie Dateien mit Leerzeichen in ihren Namen
- 11. Wie klassifiziere ich die Superklasse einer Superklasse in Swift?
- 12. TensorFlow: Wie klassifiziere ich eine binäre Sequenz mit RNN?
- 13. Wie referenziere ich Dateien mit Klammern im Namen
- 14. Liste aller versionierten Dateien in Subversion? (Dateien nach Namen entfernen)
- 15. Wie viele CSV-Dateien in Tabellen in MATLAB mit Namen importiert werden, die ihren Dateinamen entsprechen
- 16. Wie sortiere ich eine verschachtelte Sammlung nach ihren geänderten Werten?
- 17. Wie kann ich Array nach Namen sortieren?
- 18. Wie kann ich auf eine Postgres-Tabelle nach Namen zugreifen?
- 19. Wie liste ich meine Heroku-Apps zusammen mit ihren Domain-Namen auf?
- 20. Sie erhalten ihren Namen basierend auf 2 Spalten in Excel
- 21. Wie sortiere ich eine scala.collection.Map [java.lang.String, Int] nach ihren Werten?
- 22. Wie liest man Dateien aus dem Verzeichnis nach Namen?
- 23. Wie kann eine Anwendung eine DLL ohne ihren Namen laden?
- 24. Wie cache ich eine Datei durch ihren Namen anstatt Erweiterung mit. Htaccess
- 25. Wie suche ich nach einer Struktur nach Namen?
- 26. wie man den Bildschirmnamen des Prominenten von ihren Namen bekommt
- 27. Wie Objekt aus der Liste wählen und drucken ihren Namen
- 28. Dateien Einschließen/Ausschließen basierend auf Unterordner Namen
- 29. Wie kann eine Funktion ihren Namen und Argumente in R
- 30. Wie sortiere ich automatisch nach Namen in Xcode Projekt
Ihre Frage ist besser geeignet für [Super User] (http://superuser.com/tour). [Stack Overflow ist eine Frage-Antwort-Site für professionelle und enthusiastische Programmierer] (http://stackoverflow.com/tour). – Cyrus
@Cyrus, es ist ein fairer Kommentar. Es stellt sich heraus, dass es komplizierter ist als eine simple Bash-Globbing-Frage und erfordert einen vertretbaren Grad an Programmierung (wie geringfügig), obwohl der Fragesteller es zu dem Zeitpunkt, als er es fragte, nicht wusste. Also ich habe es hier beantwortet. Aber du bist richtig, wie gesagt, es ist mehr Super User orientiert. – eewanco
Vergessen Sie nicht, eine Antwort als "akzeptiert" zu markieren, wenn es für Sie funktioniert! – eewanco