Скорее всего, вам следует выбрать первую версию.
(...)
— это оператор glob, предназначенный для генерации имен файлов , а {...}
, называемый расширением фигурных скобок, предназначен для генерации строк . Во многих случаях вы можете переключаться между ними и получать те же результаты, поскольку имя файла является строкой, но между ними мало отличий. Например, учтите, что одного каталога не существует, в таком случае вы получите
$ ls (dir1|fakedir)/dir3/*.txt
dir1/dir3/file.txt
$ ls {dir1,fakedir}/dir3/*.txt
zsh: no matches found: fakedir/dir3/*.txt
Вероятно, вам нужен первый результат. Что важно, ошибка во втором случае происходит не от раскрытия фигурной скобки, а от *
! Если вы удалите его ls (dir1|dir1)/dir3
, то ls
заявляет, что не может получить доступ к fakedir/dir3
, поэтому ошибка непредсказуема (зависит от других вещей ).
Еще одно отличие состоит в том, что первая версия выводит только один результат в случае повторяющихся каталогов, тогда как вторая версия просто выводит одно и то же много раз:
$ ls (dir1|dir1)/dir3/*.txt
dir1/dir3/file.txt
$ ls {dir1,dir1}/dir3/*.txt
dir1/dir3/file.txt dir1/dir3/file.txt
Опять же, я считаю, что в большинстве случаев пользователь хочет получить первый результат.
Если вы хотите иметь полный контроль над механизмом подстановки, рекомендую ознакомиться с квалификаторами подстановок(см.man zshexpn
).
В случае bash
лучше установить параметр extglob
, который дает вам доступ к большему количеству глобусов, не таких мощных, как zsh
, но все же лучше, чем расширение фигурных скобок.
В частности, эквивалентом zsh
's (foo|bar)
в bash -O extglob
является@(foo|bar)
(этот синтаксис происходит от ksh ).
Исходя из желаемого результата, похоже, что на самом деле вы хотите сначала прочитать file2.csv
, создать сопоставление между полями, а затем применить его кfile1.csv
awk 'BEGIN{OFS=FS=","} NR==FNR{clr[$1]=$2; next} {$3=clr[$3]; print}' file2.csv file1.csv