Ich habe eine Liste von Namen wie folgt:
dog_bone
dog_collar
dragon
cool_dragon
lion
lion_trainer
dog
Ich muss Namen extrahieren, die in anderen Namen wie folgt vorkommen:
dragon
lion
dog
Ich habe die uniq
Manpage durchgesehen , aber sie scheint ganze Zeilen zu vergleichen, keine Zeichenfolgen. Gibt es eine Möglichkeit, dies mit einer Bash-Funktion zu tun?
bash
shell-script
text-processing
Fragenüberlauf
quelle
quelle
dog
,,dog_bone
unddog_bones
alle in der Datei erscheinen, was sollte ausgedruckt werden?dog
unddog_bone
würde ausgedruckt werden.Antworten:
Das führt einen
read
, zweigrep
und manchmal einenprintf
Befehl pro Zeile der Datei aus, ist also nicht sehr effizient.Sie können das Ganze in einem
awk
Aufruf erledigen :Dies bedeutet jedoch, dass die gesamte Datei im Speicher gespeichert ist.
quelle
index
macht? "index (in, find) Hiermit wird die Zeichenfolge nach dem ersten Vorkommen der Zeichenfolgensuche durchsucht und die Position in Zeichen zurückgegeben, an der dieses Vorkommen in der Zeichenfolge in beginnt."Bash
quelle
Hier ist ein Perl-Ansatz. Dies muss auch die Datei in den Speicher laden:
quelle
Ein hackiger Weg, um zu tun, was Sie wollen. Ich bin mir nicht sicher, ob alle Ihre Beispiele einen Unterstrich enthalten oder nicht, aber Sie könnten diesen abtasten und verwenden
sort | uniq -d
, um eine Liste von Teilzeichenfolgen zu erstellen, die in einer bestimmten Datei mehr als einmal vorhanden sind, wobei Sie die tatsächliche Datei selbst als Liste verwenden feste Saitengrep
über den-F
Schalter.Beispiel
Das Obige funktioniert wie folgt.
<(grep -v _ file.txt)
erzeugt eine Liste des Inhalts desfile.txt
Weglassens der Zeilen, die einen Unterstrich (_
) enthalten.grep -oFf <(..) file.txt
verwendet die Ergebnisse von # 1 als Liste von Zeichenfolgen mit fester Länge,grep
die in der Datei gefunden werdenfile.txt
.Die Ergebnisse dieses Befehls werden dann über die Befehle
sort
& ausgeführtuniq -d
, mit denen die Einträge, die mehr als einmal vorkommen, unter den Ergebnissen aufgelistet werden,grep -oFf
die erzeugt wurden.HINWEIS: Wenn Sie verstehen möchten, warum Sie
LC_ALL=C
bei der Ausführung vonsort
unduniq
Anrufe die Verwendung von verwenden müssen, sehen Sie sich hier die gute Antwort von @ Stephane an: Was macht "LC_ALL = C"? .quelle
grep -v _ file.txt
. VerwendenLC_ALL=C sort | LC_ALL=C uniq -d
stattsort -u
würde funktionierengrep -of <(grep -v _ file.txt) file.txt
gibt immer die Zeilen zurück, die keine Unterstriche enthalten, weil sie mit sich selbst übereinstimmen (Sie vermissen auch einige-F
, aber das ist ein anderes Problem).LC_ALL=C
jetzt in all Ihren Beispielen passiert . Ich bin endlich über dein A zu diesem Q gestolpert, komisch, dass ich dieses bis heute noch nie gesehen habe. Vielen Dank!foo
es innerhalb istfoo_bar
, aber nicht, oba_b
es innerhalb ista_b_c
. Es wird auch nicht funktionieren, wenn es einfoo
und gibtfoobar
.Hier ist eine
bash
Versionslösung4.x
:quelle