그래서 mkdir 명령에 전달할 수 있도록 특수 문자를 이스케이프된 해당 문자로 바꾸는 스크립트를 작성하고 싶습니다. 친구가 비슷한 줄을 사용했기 때문에 이를 사용하여 대괄호를 다음과 같은 밑줄로 바꿀 수 있습니다.
echo 'Hello (World)' | sed 's/(\|)/_/g'
하지만 다음 명령으로 변경하면 출력이 내가 원하는 것이 아닙니다.
echo 'Hello (World)' | sed 's/(\|)/\(\|\)/g'
시스템 출력: Hello (|)World(|)
원하는 출력: Hello \(World\)
이를 수행할 수 있는 방법이 있습니까? "tr" 명령을 사용하는 등 다른 사람의 제안을 사용했지만 그로부터도 원하는 출력을 얻을 수 없었습니다.
답변1
...mkdir 명령에 전달할 수 있도록 이스케이프된 해당 항목을 사용합니다.
전혀하지 마십시오. 대신에,인용하다끈:
name1="Hello (World)!"
name2="I want this to be a five-star directory (*****)"
mkdir -- "${name1}" "${name2}"
그렇지 않으면
mkdir "Hello (World)"
mkdir "I want this to be a five-star directory (*****)"
간단하고 효과적입니다.
답변2
나는 다음을 추천한다:
1. 다소 읽기 쉬운 버전
echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g'
각 호출은 브래킷 유형에 대한 것입니다. "찾기" 부분은 대괄호만 찾고, 교체 부분은 동일한 대괄호를 다시 배치하지만 백슬래시 뒤에 이스케이프해야 합니다.
2. 콤팩트
이것은 또한 작동합니다:
echo 'Hello (World)' | sed -E 's/(\(|\))/\\\1/g'
여기서는 sed를 한 번만 호출합니다.
-E
괄호 및 특수 문자와 관련하여 다르게 동작하는(그리고 더욱 "현대적"인) 확장 정규식을 사용하도록 sed에 지시합니다 . 이를 통해 캡처 그룹을 사용할 수 있습니다.
"찾기" 부분에서는 sed에게 여는 괄호나 닫는 괄호를 찾도록 지시합니다. 그들은 탈출했습니다. 전체 "( 또는)" 그룹 자체는 괄호로 묶여 있으며, 이 괄호는 sed에게 그룹에서 찾은 내용을 기억하도록 지시하는 데 사용되기 때문에 이스케이프되지 않습니다. 그런 다음 교체 부분에 백슬래시(이전처럼 이스케이프됨)를 넣고 sed가 이전에 찾은 내용을 \1
.
3. mkdir에 연결
문제의 핵심은 sed 구현에서 제공되는 출력입니다. OP가 간략하게 언급한 원래 의도에 관해서는 이 접근 방식은 약간 인위적이지만 작동합니다. "Hello (World)"라는 디렉터리의 경우 다음과 같이 작동합니다.
echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g' | sed 's/ /\\ /g' | xargs mkdir
우리도 예전처럼 이 공간에서 탈출해야 한다. Xargs는 이전 명령의 출력을 mkdir에 전달하는 데 사용됩니다. 또는:
echo 'Hello (World)' | sed 's/(/\\(/g' | sed 's/)/\\)/g' | xargs -I{} mkdir '{}'
이렇게 하면 이전 출력을 따옴표로 묶어 공백을 이스케이프하는 것을 방지할 수 있습니다(필요한 이름에 따옴표를 포함하지 않는 것이 좋습니다!).
언급했듯이 이것은 매우 고안된 것입니다. mkdir을 사용하고 단순히 이름을 따옴표로 묶는 것에 대한 또 다른 대답은 OP의 접근 방식일 수 있습니다.