Listen Sie eindeutige Dateien nur basierend auf einem Teil des Dateinamens auf

Listen Sie eindeutige Dateien nur basierend auf einem Teil des Dateinamens auf

Ich habe beispielsweise viele Dateien, die wie die folgende Ausgabe aussehen. Ich versuche, eine Liste aller eindeutigen Dateinamen zu erhalten, ignoriere dabei aber die Zeichen rechts vom "-". Ich habe es ls -la | grep ....- | sort --uniquemit einigen Variationen versucht, aber das ergibt nicht die Ausgabe, die ich brauche

4855-00160880.psi
4855-00160980.ps
4855-00160980.psi
5355-00160880.ps
5355-00160880.psi
5355-00160980.ps
5355-00160980.psi
5855-00160880.ps
5855-00160880.psi
5855-00160980.ps
5855-00160980.psi
5855-00160A80.ps
5855-00160A80.psi

Im Idealfall hätte ich gerne eine Ausgabe wie diese

4855
5355
5855

Antwort1

SeitSie wollen wirklich nicht analysierenls, das hier sollte funktionieren:

find . -type f -maxdepth 1 -exec basename "{}" \; | cut -d'-' -f1 | sort -u

Antwort2

Wie ist das?

printf "%-4.4s\n" ????-* | uniq

Die Shell erweitert die Platzhalter in alphabetischer Reihenfolge und übergibt das Ergebnis als Argumente an printf. Der Formatstring kürzt jedes Argument auf vier Zeichen und fügt eine neue Zeile hinzu. Jetzt müssen nur noch benachbarte Duplikate entfernt werden.

Wenn Sie die Anzahl der Ziffern vor dem Bindestrich nicht kennen, aber eine Idee haben, können Sie eine Schleife über einige Kandidaten ausführen:

for expr in '??' '???' '????' '?????'  # Quoted (!)
do
    printf "%-${#expr}.${#expr}\n" $expr-* |  # Unquoted!
    uniq
done

Dies verwendet die Bash-onlyParametererweiterung $[#var}wodurch die Zeichenfolgenlänge von erhalten wird $var.

Beachten Sie den Trick, die Platzhalter in Anführungszeichen zu setzen, um ihre Erweiterung bei der Initialisierung der Schleife zu vermeiden, und dann die Variable ohne Anführungszeichen innerhalb der Schleife zu verwenden (was in den meisten anderen Fällen nicht möglich ist).

Antwort3

-type fEs lohnt sich , die Antwort von DopeGhoti zu ergänzen , um dieses falsche .Ergebnis zu vermeiden.

find . -maxdepth 1 -exec basename "{}" \; | cut -d'-' -f1 | sort -u
.
4855
5355
5855
find . -maxdepth 1 -type f -exec basename "{}" \; | cut -d'-' -f1 | sort -u
4855
5355
5855
$

Wenn Sie es Ihrem ursprünglichen Versuch ähnlich halten möchten, können Sie dies verwenden (ist lsallerdings schlecht, da es analysiert wird!)

ls -1 | grep ^....-  | cut -c1-4 | sort --unique

awk-basierte Lösung, immer noch ls analysierend

ls -1 | awk -F- '{print $1}' | sort --unique

In keinem dieser Fälle ist eine Sortierung wirklich erforderlich, da lsdie Ausgabe bereits sortiert ist und Sie einfach verwenden können uniq.

ls -1 | awk -F- '{print $1}' | uniq

SED-basierte Lösung

ls -1 | sed 's/-.*//' | uniq

find / sed-Lösung, die das Parsen von ls vermeidet

find . -type f -printf "%f\n" | sed 's/-.*//g' | sort --unique

Wenn immer 4 Ziffern vor dem "-" stehen, dann ist das recht elegant

find . -type f -printf "%.4f\n" | sort -u

Antwort4

Mit zsh:

myfiles=(*-*(.))
print -rl -- ${(u)myfiles[@]%%-*}

Dadurch werden alle regulären Dateinamen, die mindestens einen Bindestrich enthalten, in einem Array gespeichert. Anschließend wird die Parametererweiterung für jedes Element des Arrays verwendet, um den ersten Bindestrich und alles Folgende zu entfernen. Alle doppelten Elemente werden über das (u)Flag entfernt.
Um auch versteckte Dateien auszuwählen, verwenden Siemyfiles=(*-*(.D))

verwandte Informationen