경로 슬래시 후 괄호 확장


12

중괄호 확장을 사용하여 파일을 다른 이름으로 동일한 디렉토리에 복사하려고합니다. bash 4.4.18을 사용하고 있습니다.

내가 한 일은 다음과 같습니다.

cp ~/some/dir/{my-file-to-rename.bin, new-name-of-file.bin}

하지만이 오류가 발생합니다.

cp: cannot stat '/home/xyz/some/dir/{my-file-to-rename.bin,': No such file or directory

이와 같은 간단한 중괄호 확장조차도 같은 오류가 발생합니다.

cp {my-file-to-rename.bin, new-name-of-file.bin}

내가 도대체 ​​뭘 잘못하고있는 겁니까?

답변:


29

중괄호 확장 구문 쉼표를 허용하지만 쉼표 뒤에 공백을 허용하지 않습니다. 많은 프로그래밍 언어에서 쉼표 뒤에 공백이 일반적이지만 여기에는 없습니다. Bash에서 인용되지 않은 공간이 있으면 괄호 확장이 수행되지 않습니다.

공간을 제거하면 작동합니다.

cp ~/some/dir/{my-file-to-rename.bin,new-name-of-file.bin}

전혀 필요하지는 않지만 후행을 .bin중괄호 밖으로 이동할 수 있습니다 .

cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin

중괄호 확장의 효과를 테스트하려는 경우 또는 을 사용 echo하거나 원하는 형식 문자열을 사용하여이를 수행 할 수 있습니다. ( Bash의 내장 기능 은 기본적으로 이스케이프 시퀀스를 확장하지 않으므로 실제로 어떤 명령이 실제로 실행 될지 확인하는 데 적합하기 때문에 개인적으로 Bash에있을 때 사용 합니다.) 예 :printf '%s 'printfechoecho

ek@Io:~$ echo cp ~/some/dir/{my-file-to-rename,new-name-of-file}.bin
cp /home/ek/some/dir/my-file-to-rename.bin /home/ek/some/dir/new-name-of-file.bin

23

string{foo, bar}괄호 확장이 아닙니다. 두 단어 string{foo,bar}입니다. 중괄호 확장을 사용하려면 중괄호가 같은 단어 내에 있어야합니다. 필요하지 않은 경우 추가 공간을 제거하거나 필요하면 인용해야합니다.

$ printf "%s\n" aa{bb, cc}
aa{bb,
cc}
$ printf "%s\n" aa{bb,cc}
aabb
aacc
$ printf "%s\n" aa{bb," cc"}
aabb
aa cc

분명한 예는 +1이며 감사합니다. 내 명성이 충분할 때 공짜를 줄 것이다. :)
nanangarsyad

"shell words"에 대해 언급해야 할 것이 있습니다. . .like 어떻게 쉘이 단어를 나눌지를 아는 방법
;;

-1

Bash는 그 공간을 다른 공간처럼 취급합니다. IFS로서, 내부 필드 분리기. 이것은 확장 후 단어 분할 및 read 내장 명령을 사용하여 행을 단어로 분할하는 데 사용됩니다.

쉘은 IFS의 각 문자를 분리 문자로 취급하고 다른 확장 결과를이 문자의 단어로 나눕니다. IFS가 설정되지 않았거나 해당 값이 정확히이면 기본값, 시퀀스,, 및 이전 확장 결과의 시작 및 끝에서 무시되며, 시작 또는 끝이 아닌 IFS 문자 시퀀스가 ​​구분됩니다. 말. IFS에 기본값 이외의 값이있는 경우 공백 문자가 IFS (ISF 공백 문자) 값에있는 한 공백 문자 및 공백 탭은 단어의 시작과 끝에서 무시됩니다. 인접한 IFS 공백 문자와 함께 IFS 공백이 아닌 IFS의 문자는 필드를 구분합니다. 일련의 IFS 공백 문자도 분리 문자로 처리됩니다. IFS의 값이 널이면
-bash (1)

이스케이프되지 않은 구분 기호를 삽입하면 bash에게 명령을 내리고 인수는 다음과 같습니다.

  1. "cp"
  2. "~ / some / dir / {my-file-to-rename.bin,"
  3. "new-name-of-file.bin}"

따옴표 나 이스케이프 "\"가 있으면 다음과 같은 결과가 나타납니다.

  1. "cp"
  2. "~ / some / dir / {my-file-to-rename.bin, \ new-name-of-file.bin}"

"new-name-of-file.bin"이 원하는 새 파일 이름이 아니면 어느 것도 원하지 않을 것입니다. 공간이 포함되어 있습니다. 괄호 확장이 먼저 수행 된 다음 물결 확장이 발생하면 bash가 다음을 실행합니다.

  1. "cp"
  2. "/path/to/home/some/dir/my-file-to-rename.bin"
  3. "/ path / to / home / some / dir / \ new-name-of-file.bin"

단순히 공간을 제거하면 모든 것이 해결됩니다.


5
이것은 대부분 좋은,하지만 당신은 단어 분리가 발생하는 말을하는 것 cp ~/some/dir/{my-file-to-rename.bin, new-name-of-file.bin}IFS결과에 영향을 미친다. 둘 다 마찬가지입니다. 여기서 공간은 토큰 화 의 메타 문자 입니다 ( 2 단계 ). 분할 발생시 3.5.7 을 참조하십시오 . IFS=x그런 다음 시도하십시오 printf '[%s]\n' {a,b} printf '[%s]\n' {a, b} printf '[%s]\n' {a,xb} printf '[%s]\n' {a, xb}.
Eliah Kagan
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.