Почему «cat {foo}» не выводит foo, а «cat {foo, bar}» делает?


12

Я пытался объединить текстовые файлы в подпапках и попытался:

cat ./{mainfolder1,mainfolder2,mainfolder3}/{subfolder1}/book.txt > out$var

Однако это ничего не вернуло. Итак, попытался добавить несуществующую подпапку2

cat ./{mainfolder1,mainfolder2,mainfolder3}/{subfolder1,subfolder2}/book.txt > out$var

И на этот раз все получилось, конкатенация файлов прошла успешно. Почему это происходит?


2
Используйте echoвместо того, catчтобы увидеть, какую командную строку вы получили. (Или используйте set -xдля отладки.)
Питер Кордес

Ответы:


22

По определению, расширение скобок в GNU Bash требует либо выражения последовательности, либо серии значений, разделенных запятыми:

Шаблоны, которые должны быть развернуты в фигурные скобки, принимают форму необязательной преамбулы, за которой следует либо последовательность строк, разделенных запятыми, либо выражение последовательности между парой фигурных скобок, за которым следует необязательный postScript.

Вы можете прочитать руководство для деталей.

Несколько простых примеров:

echo {subfolder1}
{subfolder1}

echo {subfolder1,subfolder2}
subfolder1 subfolder2

echo subfolder{1}
subfolder{1}

echo subfolder{1..2}
subfolder1 subfolder2


1

Скобки будут расширяться только в том случае, если у них есть строки, разделенные запятой, например, {abc, def} или диапазон, например, {a..e}, указанный между ними.

В вашем случае вы можете просто написать подпапку1, не заключая ее в фигурные скобки, так как в этом нет необходимости

cat ./{mainfolder1,mainfolder2,mainfolder3}/subfolder1/book.txt > out$var

К сожалению, /path/{a,}/filenameрасширяется до двух строк /path/a/filenameи /path//filename, что может быть нежелательным.
Кусалананда

спасибо @Kusalananda за исправление, да, bash выдаст предупреждение «неоднозначное перенаправление»
Neo_Returns

Нет, вы получите, ambiguous redirect если попытаетесь перенаправить в файл, заданный переменной без кавычек, которая не имеет значения, например echo 'hello' >$idontexist.
Кусалананда

1
... или если имя файла в перенаправлении будет расширено до нескольких слов. Как > *.txtс несколькими .txtфайлами, или > $fileесли $fileсодержит пробелы. Но, конечно, нет ничего неоднозначного в приведении catмножества аргументов
ilkkachu
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.