sed에서 () 안에 개행 문자를 사용하는 방법은 무엇입니까?

sed에서 () 안에 개행 문자를 사용하는 방법은 무엇입니까?

교체하고 싶을 때는 Dot다음과 같이 말하세요.

Dot
##empty line##

나는 이렇게 한다:

sed 's/Dot/Dot\
/g'

예, 문자 그대로의 새 줄이 BSD에서 작동하는 방식입니다 sed. 그러나 sed괄호 안에 있으면 동일한 작업을 수행할 수 없습니다. 명령 예:

lol=$(echo $varcontaining something | sed 's/Dot/Dot\
/g')

을 (공백) 으로 대체하기 때문입니다 .

답변1

이 Stackoverflow Q&A에 언급된 다음 방법은 어떻습니까?BSD sed에서 개행 대체를 사용하는 방법은 무엇입니까?:

sed -e 's/ /\'$'\n/g'

아니면 다른 방법으로 다음과 같이 변수에 개행 문자를 넣으세요.

cr="
"

그런 다음 변수를 사용하십시오.

sed "s/ /\\${cr}/g"

답변2

Shell은 후행 개행 문자를 제거합니다. 일반적인 해결 방법은 명령 대체 끝에 문자를 추가한 다음 제거하는 것입니다.

x=$( echo a; echo ; echo :)
echo "${x%:}"

답변3

내 생각에 가장 효율적인 방법은 아마도 를 사용하는 것입니다 eval. 쉘 확장에서 리터럴 값을 얻으려면 이를 얻는 가장 직접적인 방법은 리터럴 입력에서 가져오는 것입니다. 값은 셸의 출력에서 ​​가져온 것이므로 다시 입력해야 합니다.

일반적으로 큰 따옴표를 사용하는 것이 '가장 쉽습니다 . '하드 인용 문자열에 대한 간단한 인용 규칙은 '하드 참조를 포함할 수 없다는 것입니다. 이 컨텍스트에서 하드 참조를 해석하는 유일한 방법은 2개 이상의 인용 문자열을 함께 연결하는 것입니다.

VAR='string'\''more string'

이렇게 하면 첫 번째 인용 문자열은 두 번째 인용으로 끝나고, 두 번째 인용 문자열은 백슬래시로 이스케이프 처리된 하드 따옴표이고, 세 번째는 네 번째 하드 따옴표가 됩니다.

그렇다면 당신이 나라면 나는 어떻게 할 것 같습니까?

eval "lol='$(nl='\
';    printf %s\\n "$lol" |
      sed "s/Dot/&$nl/g
           s/'"'/&\\&&/g
          $s/$/'"'/
")"

이런 식으로 printfvar 값에 추가된 동일한 후행 개행 문자는 명령 대체에 의해 제거된 개행 문자입니다. 끝에서 두 번째 문자는 항상 큰 따옴표이므로 출력의 마지막 문자이기도 하며 이스케이프가 가능 eval하므로 문을 안전하게 분리합니다. sed가능 입력에 나타나는 큰 따옴표가 있고 문자열 시작 부분에 하나가 있습니다.

그러나 실제로 이와 같은 명령 대체를 사용하는 것은 일반적으로 좋은 습관이 아닙니다. 아마도 이것이 항상 적절한 것은 아닐 수도 있습니다. 이러한 방식으로 필터를 미세 조정하는 것보다 프로세스의 각 프로세스 루프의 모든 출력을 수집하여 단일 스트림에서 즉시 파이프라인의 다른 필터 프로세스로 전달하는 것이 더 효율적인 경우가 많습니다.

쉘 변수에 매우 큰 값이 있지 않는 한(이 역시 일반적으로 나쁜 생각입니다) 다음과 같은 방법이 더 나은 접근 방식일 수 있습니다.

set -- "$lol" 
while case "$1" in (*Dot*)
set -- "${1%Dot*}" "${1##*Dot}Dot
$2";;(*) ! lol=$1$2;; esac
do :; done

답변4

\n캐리지 리턴과 함께 줄 바꿈을 사용할 수 있습니다 \r. sed테스트할 BSD가 없지만 GNU에서 작동 합니다 sed.

$ var=Dot
$ lol=$(echo $var | sed 's/Dot/Dot\n\r/g')
$ echo "$lol"
Dot

$

BSD가 sed이를 지원하지 않으면 \r또 다른 (다소 추악한) 해결책은 다음을 사용 \n\r하거나 echo -e인쇄하는 것입니다 printf.

lol=$(echo $var | sed "s/Dot/Dot\\$(printf '\n\r')/g")

관련 정보