Ich habe folgende Dateien:
Codigo-0275_tdim.matches.tsv
Codigo-0275_tdim.snps.tsv
FloragenexTdim_haplotypes_SNp3filter17_single.tsv
FloragenexTdim_haplotypes_SNp3filter17.tsv
FloragenexTdim_SNP3Filter17.fas
S134_tdim.alleles.tsv
S134_tdim.snps.tsv
S134_tdim.tags.tsv
Ich möchte die Anzahl der Dateien zählen, snp
deren Name das Wort (Groß- und Kleinschreibung beachten) enthält. Ich habe es versucht
grep -a 'snp' | wc -l
aber dann wurde mir klar, dass grep
in den Dateien gesucht wird. Was ist der richtige Befehl zum Durchsuchen der Dateinamen?
Antworten:
Meinen Sie damit, nach dem Sie suchen möchten
snp
in den Dateinamen ? Das wäre ein einfacher Shell Glob (Wildcard), der wie folgt verwendet wird:Lassen Sie die
-q
Flagge weg, wenn Ihre Version vonls
sie nicht erkennt. Es behandelt Dateinamen mit "seltsamen" Zeichen (einschließlich Zeilenumbrüchen).quelle
ls
Dateinamen mit einem bestimmten Text abrufen könnte . Das hat aber funktioniert, danke.ls
mit den Dateinamen überein , es ist die Shell.ls
sieht eine Liste von Dateien, die dem Muster entsprechen; es ist nicht sehen , das Muster selbst.Wenn Sie ruhig in den Gängen von Unix & Linux stehen und genau zuhören, hören Sie eine gespenstische Stimme, die erbärmlich jammert: "Was ist mit Dateinamen, die Zeilenumbrüche enthalten?"
oder, in äquivalenter Weise ,
gibt alle Dateinamen aus, die
snp
jeweils eine neue Zeile enthalten, aber auch alle neuen Zeilen in den Dateinamen enthalten , und zählt dann die Anzahl der Zeilen in der Ausgabe. Wenn es eine Datei gibt, deren Name istf o o s n p \n b a r . t s v
dann wird dieser Name als ausgeschrieben
was natürlich als zwei Zeilen gezählt wird.
Es gibt einige Alternativen, die zumindest in einigen Fällen besser sind:
Das zählt die Zeilen, die enthalten
snp
, so dass dasfoosnp(\n)bar.tsv
Beispiel von oben nur einmal zählt. Eine leichte Abweichung davon istDie beiden oben genannten Befehle unterscheiden sich darin:
ls -f
wird Dateien enthalten, deren Namen mit beginnen.
;printf … *
Dies ist nicht der Fall, es sei denn, diedotglob
Shell-Option ist festgelegt.printf
ist eine eingebaute Muschel;ls
ist ein externer Befehl. Daherls
könnten die etwas mehr Ressourcen verbrauchen.*
, sortiert sie die Dateinamen.ls -f
sortiert die Dateinamen nicht. Daher verbrauchen diels
möglicherweise etwas weniger Ressourcen.Aber sie haben etwas gemeinsam: Sie geben beide falsche Ergebnisse, wenn Dateinamen vorhanden sind, die Zeilenumbrüche enthalten und
snp
sowohl vor als auch nach dem Zeilenumbruch stehen .Ein weiterer:
Dadurch wird eine Shell-Array-Variable erstellt, in der alle enthaltenen Dateinamen aufgelistet
snp
sind. Anschließend wird die Anzahl der Elemente im Array angegeben. Die Dateinamen werden als Zeichenfolgen und nicht als Zeilen behandelt, sodass eingebettete Zeilenumbrüche kein Problem darstellen. Es ist denkbar, dass dieser Ansatz ein Problem haben könnte, wenn das Verzeichnis sehr groß ist, da die Liste der Dateinamen im Shell-Speicher gespeichert werden muss.Noch ein anderer:
Früher, als wir sagten
printf "%s\n" *snp*
,printf
wiederholte (wiederverwendete) der Befehl die"%s\n"
Formatzeichenfolge einmal für jedes Argument in der Erweiterung von*snp*
. Hier nehmen wir eine kleine Änderung vor:Dadurch wird die
"%.0s\n"
Formatzeichenfolge für jedes Argument in der Erweiterung von einmal wiederholt (wiederverwendet)*snp*
. Bedeutet"%.0s"
aber, die ersten Nullzeichen jeder Zeichenfolge zu drucken - dh nichts. Dieserprintf
Befehl gibt nur eine neue Zeile (dh eine leere Zeile) für jede Datei aus, diesnp
ihren Namen enthält . und dannwc -l
werden sie zählen. Und wieder können Sie die.
Dateien durch Festlegen einschließendotglob
.quelle
Abstrakt:
Funktioniert für Dateien mit "ungeraden" Namen (einschließlich neuer Zeilen).
Beschreibung
Da ein einfacher Glob mit jedem Dateinamen
snp
in seinem Namen übereinstimmt,echo *snp*
könnte ein einfacher für diesen Fall ausreichen, aber um wirklich zu zeigen, dass nur drei Dateien übereinstimmen, verwende ich:Das einzige verbleibende Problem ist das Zählen der Dateien. Ja, grep ist eine übliche Lösung, und das Zählen neuer Zeilen mit
wc -l
ist auch eine übliche Lösung. Beachten Sie, dassgrep -c
(count) wirklich zählt, wie oft einesnp
Zeichenfolge übereinstimmt. Wenn ein Dateiname mehr als einesnp
Zeichenfolge enthält, ist die Anzahl falsch.Wir können es besser machen.
Eine einfache Lösung besteht darin, die Positionsargumente festzulegen:
Um zu vermeiden, dass die Positionsargumente geändert werden, können wir jedes Argument in ein Zeichen umwandeln und die Länge der resultierenden Zeichenfolge drucken (für die meisten Shells):
Oder, um eine Unterschale zu vermeiden:
Dateiliste
Liste der Dateien (von der ursprünglichen Frage mit einer mit einem hinzugefügten Zeilenumbruch):
Das wird eine Datei mit einem Zeilenumbruch in der Mitte haben:
f o o s n p \n b a r . t s v
Und um die Glob-Expansion zu testen:
Dadurch wird ein Sternchen hinzugefügt, das, wenn es nicht in Anführungszeichen steht, auf die gesamte Liste der Dateien erweitert wird.
quelle
Angenommen, Sie wollten die Anzahl der HTML-Dateien zählen:
Wenn Sie also das Auftreten von "snp" zählen:
quelle