- 달 이름을 딴 12개의 디렉토리를 만들고 싶습니다. 그래서 파이프를 사용하여
locale
월 이름을 가져오고tr
쉼표로 구분한 다음 중괄호로 감싸서 에 전달하려고 시도했지만mkdir
전체가 하나의 문자열로 처리됩니다. 이것을 피할 수 있는 방법이 있나요?
16:07: temp ⧲ mkdir {$(locale mon | tr \; ,)}
16:18: temp ⧲ ls -lh
total 4.0K
drwxr-xr-x. 2 john john 4.0K Dec 11 16:18 {January,February,March,April,May,June,July,August,September,October,November,December}
16:18: temp ⧲
답변1
로 사용입력 필드 구분 기호분할 출력 locale man
:
IFS=';'
mkdir -- $(locale mon)
답변2
이와 같이 중괄호 확장을 사용할 수 없으며 xargs
대신 다음을 사용하십시오.
locale mon | tr ';' '\n' | xargs mkdir
답변3
일반적으로 이와 같은 명령 대체(또는 매개변수 확장)와 함께 중괄호 확장을 사용하지 않습니다.
Bash 확장 중괄호 확장은 매우 불편하기 때문에 Bash에서는 불가능합니다.첫 번째; zsh에서는 그렇지 않습니다. 왜냐하면 zsh는 중괄호 확장 전에 명령 대체 및 매개변수 확장을 확장하지만 중괄호 확장을 위해서는 리터럴 중괄호와 쉼표가 필요하기 때문입니다.
하지만 ksh를 사용하면 쉼표와 중괄호가 어디에서 왔는지 신경 쓰지 않는 것 같기 때문에 이 작업을 수행할 수 있습니다. 이것은 시도한 것과 같이 작동합니다.
ksh$ mkdir {$(locale mon | tr \; ,)}
비교하다:
# this brace expands
ksh$ x=abc,def; echo {$x}
abc def
# increasingly silly, but also expands
ksh$ x="foo{abc" y=",def}"; echo $x$y
fooabc foodef
# it doesn't work like that in zsh
zsh% x=abc,def; echo {$x}
{abc,def}
# this works sensibly though, the comma is just part of the data
zsh% x=abc,def y=ghi; echo {$x,$y}xyz
abc,defxyz ghixyz
# this also makes sense
zsh% a=1 b=4; echo {$a..$b}
1 2 3 4
# but Bash just fails with it
bash$ a=1 b=4; echo {$a..$b}
{1..4}
그러나 정말로 원한다면 eval
Bash에서도 다음을 사용하여 확실히 할 수 있습니다.
eval "mkdir {$(locale mon | tr \; ,)}"
신뢰할 수 없는 입력 처리에 대한 일반적인 주의 사항이 모두 포함되어 있지만 다른 답변의 솔루션을 사용하는 것이 더 좋습니다.
답변4
{x,y}
예버팀대 확장(원래 70년대 csh에서 유래), 아니요매개변수 확장.
fish
셸 에서 목록 확장은 csh 매개변수 확장처럼 작동합니다.
예를 들어:
> echo //(string split -- ';' (locale mon))//
//January// //February// //March// //April// //May// //June// //July// //August// //September// //October// //November// //December//
그것은 다음과 같습니다:
% echo //{January,February,...}//
//January// //February// //...//
csh(또는 csh의 기능을 복사하는 쉘)에서.
에서는 Bourne/csh 또는 Korn과 유사한 쉘 대신 fish
명령 대체가 이루어집니다 .(cmd)
`cmd`
$(cmd)
이 경우 rc 쉘에서도 마찬가지입니다.
; echo //^``(';
'){locale mon}^//
//January// //February// //March// //April// //May// //June// //July// //August// //September// //October// //November// //December//
에서는 rc
명령이 `cmd
or 로 대체되며 대신 구분 기호 목록을 지정하는 형식이 `{more complex cmd}
있습니다 . 여기서는 출력 끝의 개행 문자가 마지막 요소에 포함되는 것을 원하지 않기 때문에 및 개행 문자를 모두 사용하고 있음을 알 수 있습니다 . 개행으로 분할하고 각 요소를 한 줄에 하나씩 출력합니다.``(seps){cmd}
$ifs
;
locale mon
fish
string split
fish
1이 아닌 요소 수가 포함된 두 개의 목록이 연결될 때 확장 또는 csh 스타일 중괄호 확장과 다릅니다 .
$ rc -c 'echo `{seq 3}^`{seq 3}'
11 22 33
$ fish -c 'echo (seq 3)(seq 3)'
11 12 13 21 22 23 31 32 33
$ fish -c 'echo (seq 2)(seq 3)'
11 12 13 21 22 23
$ rc -c 'echo `{seq 2}^`{seq 3}'
rc: line 0: bad concatenation
이 옵션이 켜져 있으면 zsh의 매개변수 확장은 처럼 작동 rc
하거나 실제로는 fish
csh 스타일 중괄호 확장과 더 유사하게 작동합니다. rcexpandparam
그리고 이 확장 스타일은 구문을 사용하여 확장별로 활성화할 수 있습니다 $^param
.
매개변수 확장 시 명령 대체도 가능합니다.
$ echo //${(s[;])^"$(locale mon)"}//
//January// //February// //March// //April// //May// //June// //July// //August// //September// //October// //November// //December//
여기에서 $(cmd)
명령 대체는 대부분의 다른 쉘과 마찬가지로 후행 개행 문자를 제거하며 s[;]
여기서 인수 확장 플래그는 인용된 대체 분할 ;
에 의존하기보다는 적용됩니다 $IFS
.
zsh/langinfo
zsh에는 모듈에서 현지화된 월 이름 목록을 가져오는 기능도 내장되어 있습니다.
$ zmodload zsh/langinfo
$ echo //${(v)^langinfo[(I)MON_<1-12>]}//
//January// //February// //March// //April// //May// //June// //July// //August// //September// //October// //November// //December//
1 요소에 개행 문자를 포함시키는 것이 가능하지만 매우 번거롭습니다.