Unterschied zwischen {1,2,3} und {1..3}

17

Gibt es einen Unterschied zwischen den Sequenzen {1,2,3}und {1..3}?

Zum Beispiel, wenn ich einige Dateien habe

file.1
file.2
file.3

und ich möchte catsie zusammen benutzen ist es sicher cat file.{1..3} > file?

Ich weiß, dass cat file.*>filedies zu Problemen führen kann, da die Shell die Dateien manchmal zufällig erweitern kann (ich denke, das hängt von den Inodes ab, oder?)

syss
quelle
1
usecat file.[123] >file
mikeserv
3
Die Reihenfolge der Expansion file.*ist nicht abhängig von den Inodes. Es sortiert sie immer lexikografisch, was von Ihrer Lokalisierungseinstellung abhängen kann.
Barmar
1
"Hängt von den Inodes ab" klingt wie eine Phase aus einer der besser recherchierten Criminal-Minds-eqsue "Computer" -Szenen.
Alec Teal
1
@mikeserv, ich glaube, ich habe es verstanden - es ist ein Shell-Glob, also erweitert es sich nur auf Dateien, die tatsächlich existieren, oder? Vs. file.{1..3}was sich auf alle drei ausdehnt, ob sie existieren oder nicht.
Wildcard
1
@Wildcard - richtig, solange mindestens eine existiert. Wenn nicht, wird es überhaupt nicht erweitert und es treten catFehler mit file.[123] not foundoder etwas sehr Nützliches auf.
mikeserv

Antworten:

18

{1..3}und {1,2,3}produzieren das gleiche Ergebnis, aber auf andere Weise.

In der Regel {n1..n2}(die zuerst zshkam bashund kshspäter kopierte), wo n1und n2sind ganze Zahlen produzieren alle Zahlen zwischen n1und n2. Während {x,y,z}drei Zeichen erzeugen x, yund z.

In Ihrem Fall sind Sie sicher zu bedienen cat file.{1..3} > file

In diesem Fall cat file.*>filehaben Sie die Shell-Globbing-Methode verwendet , bei der alle Dateinamen beginnen file.und das Ergebnis anhand der Sortierreihenfolge in der aktuellen Ländereinstellung sortiert wird.

Sie sind immer noch sicher, aber nicht mehr, wenn Sie mehr als 10 Dateien haben. {1..10}werde dir geben 1 2 3 4 5 6 7 8 9 10. Während mit Globbing, werden Sie bekommen1 10 2 3 4 5 6 7 8 9

cuonglm
quelle
8

Der Unterschied besteht darin, dass einer eine Liste und der andere eine Sequenz ist. {1,2,3}erweitert , um drei bestimmte Elemente, 1, 2, und 3. {1..3}Erweitert die Liste der Zahlen zwischen eins und drei. In diesem speziellen Fall sind sie identisch und Sie können eine der beiden Optionen verwenden. file.*wird auf alle Dateien und Verzeichnisse im aktuellen Verzeichnis erweitert, deren Name mit beginnt file.. Wenn Sie nur haben file.1, file.2und file.3dann ist das auch gleichbedeutend mit den anderen beiden.

Was die verursachenden Probleme angeht, verstehe ich nicht warum. Sie könnten darüber nachdenken

$ cat file.* > file.txt
cat: file.txt: input file is output file

Das ist jedoch ein ganz anderes Thema. Das einzige andere Problem, an das ich denken kann, ist, dass Ihre Shell die Dateien möglicherweise nicht in der richtigen Reihenfolge auflistet. Beispielsweise:

$ touch file1 file11 file2
$ echo file*
file1 file11 file2

Um das zu lösen, können Sie zshanstelle von bash(siehe hier für Details) verwenden:

% echo f*(n)
file1 file2 file11

Im Allgemeinen sind die drei Ansätze nicht gleich. Es hängt davon ab, was Sie tun möchten. In den Fällen, in denen die drei dann die gleiche Ausgabe zurückgeben, können Sie eine von ihnen verwenden. Es macht keinen Unterschied. Alle diese Erweiterungen werden von der Shell ausgeführt und erfolgen, bevor sie an einen beliebigen Befehl übergeben werden, der sie verwendet.

terdon
quelle
*Wäre es nicht problematisch, wenn ich mehr oder gleich 10 Dateien hätte, wenn ich auf die richtige Reihenfolge angewiesen wäre?
Syss
1
@syss nein. Es wäre ein Problem, wenn Sie mehr als ARG_MAXDateien hätten, aber das wird viel, viel mehr als 10 sein.
terdon
1
@terdon Er fragte, ob sie in numerischer Reihenfolge angezeigt werden (dh nicht "1, 10, 2"), nicht, ob sie das Argument-Array überlaufen.
Random832
3
@terdon Ich denke, @syss ist richtig, dass die Ausgabe von cat *nicht gut definiert ist. Die Ausgabe hängt von der Shell und der Umgebung ab. Siehe Sebastians Kommentar .
Marco
Wird .txtdas Problem durch Hinzufügen nicht gelöst file.*?
Ismael Miguel
6

Sie sind gleich, aber es hängt von der installierten Bash-Version ab, ob sie verfügbar sind.

Von dieser Seite:

{xxx,yyy,zzz,...} probably in all bash versions

{a..z} introduced in bash 3

{<START>..<END>..<INCR>} new in bash 4
cristi
quelle