문자의 첫 번째 인스턴스와 모든 후속 문자를 바꾸도록 sed 명령을 개선하시겠습니까?

문자의 첫 번째 인스턴스와 모든 후속 문자를 바꾸도록 sed 명령을 개선하시겠습니까?

입력하다:

<e1 name="file1" id="id1" anotherId="id2">

원하는 출력:

file1

다음과 같이 필요한 것을 얻을 수 있습니다.

echo '<e1 name="file1" id="id1" anotherId="id2">' | sed 's/\(.*name="\)\(.*\)\(".*\)/\2/' | sed 's/".*//'

산출:file1

가능하다면 명령 세트를 개선하고 sed의 마지막 파이프를 제거하고 싶습니다. sed의 마지막 파이프를 제거하면 원하는 결과를 얻을 수 없습니다.

echo '<e1 name="file1" id="id1" anotherId="id2">' | sed 's/\(.*name="\)\(.*\)\(".*\)/\2/'

산출:

file1" id="id1" anotherId="id2

보시다시피 sed는 file1 다음의 첫 번째 인용문이 아닌 마지막 인용문을 선택했습니다.

누구든지 이 명령을 개선하는 데 도움을 줄 수 있나요?

답변1

echo '<e1 name="file1" id="id1" anotherId="id2">' |
  sed -n 's/.*name="\([^"]*\)".*/\1/p'

또는 GNU 사용( grepPCRE 지원으로 구축된 경우):

echo '<e1 name="file1" id="id1" anotherId="id2">' |
  grep -Po 'name="\K[^"]*'

답변2

sed

이 버전을 사용하면 조금 단순화할 수 있습니다.

$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
   sed 's/.*name="\(.*\)" id.*/\1/'

모든 것을 괄호로 묶을 필요는 없습니다. 나중에 삭제할 수 있도록 관심 있는 항목을 저장하면 됩니다.

grep

grepPerl의 정규식 엔진(PCRE) 기능을 사용할 수도 있습니다 .

$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
   grep -Po '(?<=name=")(\w+)(?=")'

이는 PCRE의 미래 지향적 및 과거 지향적 기능을 활용합니다. 이 표기법은 다음과 같은 문자 시퀀스를 찾습니다."name=" 앞으로우리는 무엇을 찾고 있습니까? 이 비트는 그것을하고 있습니다 :

(?<=name=")

그런 다음 우리가 실제로 찾고 있는 일련의 단어 문자를 찾습니다.

(\w+)

앞을 내다보는 마지막 요점은 다음과 같습니다.

(?=")

"따옴표( ) 를 찾고 있습니다 .뒤쪽에우리는 무엇을 찾고 있습니까?

$ echo '<e1 name="file1" id="id1" anotherId="id2">' | \
   awk '{gsub("\"","");split($2,a,"="); print a[2]}'

이 변형은 전역 대체를 위해 큰따옴표(``"``)를 문자열로 만듭니다.

gsub("\"","")

나머지 문자열은 다음과 같습니다.

<e1 name=file1 id=id1 anotherId=id2>

따라서 awk일반처럼 분할하면 두 번째 열이 우리가 관심 있는 부분이 됩니다. 그것은 될 것 $2입니다 awk. 따라서 해당 변수를 가져와 등호( =)로 나눌 수 있습니다.

split($2,a,"=");

그러면 $2결과가 분할되어 배열에 저장 됩니다 a. 그런 다음 등호 오른쪽에 있는 모든 항목인 배열의 두 번째 요소를 인쇄할 수 있습니다 $2.

file1

관련 정보