Різниця між {1,2,3} та {1..3}


17

Чи є різниця між послідовностями {1,2,3}та {1..3}?

Наприклад, якщо у мене є деякі файли

file.1
file.2
file.3

і я хочу, щоб catвони разом це безпечно використовувати cat file.{1..3} > file?

Що я знаю, це cat file.*>fileможе спричинити проблеми, тому що оболонка може іноді розширювати файли випадковим чином (я думаю, це залежить від входів, чи не так?)


1
використанняcat file.[123] >file
mikeserv

3
Порядок розширення file.*не залежить від вузлів. Це завжди сортує їх лексикографічно, що може залежати від вашого місця розташування.
Бармар

1
"Залежить від внутрішніх" звучить як фаза з однієї з кращих досліджених злочинних умів - "комп'ютерних" сцен.
Alec Teal

1
@mikeserv, я вважаю, що це зрозуміло - це глобус оболонки, тому він розширюється лише до файлів, які існують насправді, правда? Vs. file.{1..3}яка розширюється на всі три, існують вони чи ні.
Wildcard

1
@Wildcard - правильно, доки існує хоча б одна, тобто. Якщо ні, то вона не розширюється зовсім, а catпомилки з file.[123] not foundчимось дуже корисним.
mikeserv

Відповіді:


18

{1..3}і {1,2,3}дають той же результат, але по-іншому.

Загалом, {n1..n2}(який прийшов сьогодні з zsh, bashі kshскопіював його пізніше) , де n1і n2цілі числа виробляють все числа між n1і n2. Поки {x,y,z}виробляють три символи x, yі z.

У вашому випадку ви безпечні у використанні cat file.{1..3} > file

Тепер, у випадку з cat file.*>file, ви використовували глобальну оболонку , яка виробляє все ім'я файлу, починаючи з file.цього результату, і результат буде відсортований на основі порядку порівняння у поточному мові.

Ви все ще в безпеці, але вже не тоді, коли у вас більше 10 файлів. {1..10}дасть тобі 1 2 3 4 5 6 7 8 9 10. Поки з глобусом ви отримаєте1 10 2 3 4 5 6 7 8 9


8

Різниця полягає в тому, що один - це список, а інший - послідовність. {1,2,3}розширюється до трьох конкретних елементів, 1, 2, і 3. {1..3}розширюється до списку чисел від одного до трьох. У цьому конкретному випадку вони однакові, і ви можете використовувати будь-яке з двох. file.*розшириться на всі файли та каталоги в поточному каталозі, з якого починається ім'я file.. Якщо у вас є тільки file.1, то file.2і file.3це теж еквівалентно двом іншим.

Що стосується її спричинення проблем, я не розумію, чому. Ви можете задуматися

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

Це, однак, зовсім інше питання. Єдина інша проблема, яку я можу придумати, - це те, що ваша оболонка може не перераховувати файли у правильному порядку. Наприклад:

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

Щоб вирішити це, ви можете використовувати zshзамість bash(детальніше див. Тут ):

% echo f*(n)
file1 file2 file11

Загалом, три підходи не однакові. Це залежить від того, що ви хочете зробити. У тих випадках, коли троє повертають один і той же результат, так, так, ви можете використовувати будь-який з них. Це не має ніякої різниці. Усі ці розширення виконуються оболонкою і відбуваються до того, як вони будуть передані будь-якій команді, яка їх використовує.


Чи не виникне проблема з тим, *якби у мене було більше або рівних 10 файлів, якщо я залежу від правильного порядку?
syss

1
@syss ні. Було б проблемою, якби у вас було більше ARG_MAXфайлів, але це буде так, набагато більше 10.
terdon

1
@terdon Він запитував, чи відображатимуться вони в числовому порядку (тобто не "1, 10, 2"), а не якщо вони переповнять масив аргументів.
Випадково832

3
@terdon Я думаю, що @syss має рацію, що результат cat *недостатньо визначений. Вихід залежить від оболонки та середовища. Дивіться коментар Себастьяна .
Марко

Не вдасться додати .txtвирішити проблему file.*?
Ісмаїл Мігель

6

Вони однакові, але це залежить від встановленої вами версії bash, якщо вони є в наявності.

З цієї сторінки:

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

{a..z} introduced in bash 3

{<START>..<END>..<INCR>} new in bash 4
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.