경로 슬래시 이후 Bash 버팀대 확장

경로 슬래시 이후 Bash 버팀대 확장

중괄호 확장을 사용하여 다른 이름의 파일을 동일한 디렉터리에 복사하려고 합니다. 나는 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}

내가 뭘 잘못했나요?

답변1

이것버팀대 확장구문에는 쉼표가 허용되지만 쉼표 뒤의 공백은 허용되지 않습니다. 많은 프로그래밍 언어에서는 쉼표 뒤의 공백이 일반적이지만 여기서는 그렇지 않습니다. 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또는 printf '%s ', 또는을 사용할 수 있습니다.printf이를 수행하려면 원하는 형식 문자열을 사용하세요. (개인적으로 echoBash에 있을 때 이것을 사용하는 이유는 다음과 같습니다.배쉬 echo내장이스케이프 시퀀스는 기본적으로 확장되지 않으므로 실행된 실제 명령을 검사하는 데 이상적입니다. )예를 들어:

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

답변2

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

답변3

Bash는 이 공간을 다른 공간과 마찬가지로 취급합니다. IFS로서 내부 필드 구분 기호입니다. 이는 확장된 단어 분할에 사용되며 read 내장 명령을 사용하여 행을 단어로 분할합니다.

쉘은 IFS의 각 문자를 구분 기호로 처리하고 다른 확장 결과를 이러한 문자의 단어로 분할합니다. IFS가 설정되지 않았거나 해당 값이 기본값인 경우 이전 확장 결과의 시작과 끝 부분에 있는 , 및 시퀀스는 무시되고 시작이나 끝에 있지 않은 IFS 문자 시퀀스는 구분하는 데 사용됩니다. 단어. IFS에 기본값이 아닌 값이 있는 경우 공백 문자가 IFS 값(IFS 공백)에 있는 한 단어의 시작과 끝 부분에 있는 공백과 탭 시퀀스는 무시됩니다. IFS 공백이 아닌 IFS의 모든 문자와 인접한 IFS 공백 문자가 함께 필드를 구분합니다. 공백 문자의 IFS 시퀀스도 구분 기호로 간주됩니다. IFS 값이 비어 있으면 단어 분할이 발생하지 않습니다.
-배쉬(1)

이스케이프되지 않은 구분 기호를 삽입하면 명령과 인수가 다음과 같다는 것을 bash에 알릴 수 있습니다.

  1. "cp"
  2. "~/some/dir/{이름을 바꿀 파일.bin"
  3. "새 파일 이름.bin}"

따옴표나 이스케이프 문자 "\"가 있는 경우 다음을 수행합니다.

  1. "cp"
  2. "~/some/dir/{이름을 바꿀 파일.bin,\새 파일 이름.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/\ 새 파일 이름.bin"

공간만 제거하면 모든 문제가 해결됩니다.

관련 정보