sed를 사용하여 (***)를 \(***\)로 바꾸는 방법

sed를 사용하여 (***)를 \(***\)로 바꾸는 방법

그래서 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의 접근 방식일 수 있습니다.

관련 정보