
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 --unique
mit 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 f
Es 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 ls
allerdings 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 ls
die 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))