cygwin에서 sed 따옴표와 백 슬래시


1

cygwin에서 sed로 문자열에서 부분 문자열을 추출하려고합니다.

#!/bin/bash

var1="foo\ bar"
var2="baz"

var3="$var1 $var2"

# extract "foo\ bar" from "foo\ bar baz"
var4=`echo $var3 | sed "s/"$var1"//"`
echo "$var4"

하지만 백 슬래시로 인해서 다음과 같은 결과가 나옵니다. sed : -e expression # 1, char 6 : unterminated`s 'command

어떻게 'baz'를 출력하기 위해 sed 명령을 쓸 수 있습니까?

답변:


2

문제는 쉘과 sed백 슬래시 해석입니다. sed이 작업을 올바르게 수행 할 수는 있지만 Perl과 같은 다른 도구를 사용하는 것이 좋습니다.

#!/bin/bash
export var1="foo\ bar" ## The export allows Perl to access the variable as $ENV{var1}
var2="baz"
var3="$var1 $var2"

# extract "foo\ bar" from "foo\ bar baz"
var4=`echo $var3 | perl -ne '$var1=quotemeta($ENV{var1}); s/$var1//; print'`
echo "$var4"

위 예제는 quotemeta모든 비 ASCII 문자를 이스케이프 하는 Perl 함수를 사용 하여 정규 표현식이 백 슬래시와 정확하게 일치 할 수있게합니다.

마지막으로, 왜 이것을하고 싶습니까? 당신은 정말 일치해야합니까 \하거나 bash는 문자열에 공백을 일치 시키려면? 그렇다면 더 쉬운 방법이 있습니다.


1
펄 스크립트는 약간 골프 될 수 있습니다 :perl -pe "s/\Q$var1//"
glenn jackman

@ 글렌 잭맨 멋지다! 나는 \ Q를 약식으로 사용 quotemeta합니까? 내가 그 대답을 바꾸지는 않겠지 만 그게 더 명확 해졌지만 그 사실을 알면 좋다. 고마워.
terdon

1

간단히 말하자면 .... coloumns와 마찬가지로 더 많은 행 지향적 접근 방식을 취합니다. 명령을 강요하면 안된다. Cut은 더 좋고 / 더 간단한 옵션이 될 것입니다.

양자 택일로 substring 추출이 당신이 찾고있는 것이면 awk 또한 적합합니다 ... 예제

Kaizen ~/so_test
$ echo "foo\ bar baz" | awk '{print substr($0,1,8)}'
+ echo 'foo\ bar baz'
+ awk '{print substr($0,1,8)}'
foo\ bar

이 경우에 사용하기가 더 쉽기 때문에 충분합니까?


0

이 작업을 sed와 함께 사용하려면 백 슬래시를 벗어나야합니다. 광기에 대비하십시오.

$ echo "$var1"
foo\ bar
$ echo "$var3"
foo\ bar baz
$ echo "$var3" | sed "s/$var1//"
foo\ bar baz
$ echo "${var1//\\/\\\\}"
foo\\ bar
$ echo "$var3" | sed "s/${var1//\\/\\\\}//"
 baz

물론 이스케이프가 필요한 많은 문자가 있습니다. *@ terdon의 펄 응답이 이쑤시개 숲보다 낫습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.