입력하다:
<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 사용( grep
PCRE 지원으로 구축된 경우):
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
grep
Perl의 정규식 엔진(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