Differenza tra {1,2,3} e {1..3}


17

C'è una differenza tra le sequenze {1,2,3}e {1..3}?

Ad esempio se ho alcuni file

file.1
file.2
file.3

e li voglio catinsieme è sicuro da usare cat file.{1..3} > file?

Quello che so è che cat file.*>filepotrebbe causare problemi perché la shell può espandere i file in modo casuale a volte (penso che questo dipenda dagli inode, vero?)


1
usocat file.[123] >file
mikeserv il

3
L'ordine di espansione di file.*non dipende dagli inode. Li ordina sempre lessicograficamente, il che potrebbe dipendere dalle impostazioni di individuazione.
Barmar,

1
"dipende dagli inode" sembra una fase di una delle scene "informatiche" meglio studiate di criminali-menti-eqsue.
Alec Teal,

1
@mikeserv, credo di averlo capito: è un shell glob, quindi si espande solo ai file che esistono realmente, giusto? Vs. file.{1..3}che si espande a tutti e tre indipendentemente dal fatto che esistano o meno.
Wildcard

1
@Wildcard - giusto, fintanto che ne esiste almeno una. Altrimenti non si espande per niente ed caterrori con file.[123] not foundo qualcosa di molto utile.
Mikeserv,

Risposte:


18

{1..3}e {1,2,3}produce lo stesso risultato, ma in modo diverso.

In generale, {n1..n2}(che è venuto prima da zsh, bashe kshcopiati in un secondo momento), dove n1e n2sono interi produrre tutti i numeri tra il n1e n2. Mentre {x,y,z}produce tre personaggi x, ye z.

Nel tuo caso, sei sicuro da usare cat file.{1..3} > file

Ora, in caso di cat file.*>file, hai usato il globbing della shell , che produce tutto il nome del file con cui iniziare file.e il risultato verrà ordinato in base all'ordine di confronto nella locale corrente.

Sei ancora al sicuro, ma non più quando hai più di 10 file. {1..10}ti darà 1 2 3 4 5 6 7 8 9 10. Mentre con il globbing, otterrai1 10 2 3 4 5 6 7 8 9


8

La differenza è che uno è un elenco e l'altro una sequenza. {1,2,3}espande a tre elementi specifici, 1, 2, e 3. {1..3}si espande nell'elenco dei numeri tra uno e tre. In questo caso particolare, sono gli stessi e puoi usare uno dei due. file.*si espanderà a tutti i file e le directory nella directory corrente il cui nome inizia con file.. Se solo tu hai file.1, file.2e file.3allora anche quello equivale alle altre due.

Per quanto riguarda i suoi problemi che causano, non vedo perché. Potresti pensare

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

Questo, tuttavia, è un problema completamente diverso. L'unico altro problema che mi viene in mente è che la shell potrebbe non elencare i file nell'ordine corretto. Per esempio:

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

Per risolverlo, puoi usare zshinvece di bash(vedi qui per i dettagli):

% echo f*(n)
file1 file2 file11

In generale, i tre approcci non sono gli stessi. Dipende da cosa vuoi fare. In quei casi in cui i tre restituiscono lo stesso output, sì, puoi usarne uno qualsiasi. Non fa differenza. Tutte queste espansioni vengono eseguite dalla shell e avvengono prima di essere passate a qualunque comando le usi.


non ci sarebbe un problema *se avessi 10 o più file uguali, se dipendo dal giusto ordine?
syss,

1
@syss no. Sarebbe un problema se tu avessi più di ARG_MAXfile ma sarà molto, molto più di 10.
terdon

1
@terdon Stava chiedendo se appariranno in ordine numerico (cioè non "1, 10, 2"), non se supereranno l'array di argomenti.
Casuale 832,

3
@terdon Penso che @syss abbia ragione sul fatto che l'output di cat *non sia ben definito. L'output dipende dalla shell e dall'ambiente. Vedi il commento di Sebastian .
Marco,

L'aggiunta non .txtrisolverà il problema con file.*?
Ismael Miguel,

6

Sono gli stessi, ma dipende dalla versione bash che hai installato se sono disponibili.

Da questa pagina:

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

{a..z} introduced in bash 3

{<START>..<END>..<INCR>} new in bash 4
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.