콜론으로 구분된 작업 문자열이 있는데 각 형식은 a=b
foo를 추출하기 위해 구문 분석해야 합니다. 여기서 foo는 입니다 ...:di=foo:...
. 할당은 di=foo
문자열의 시작, 중간 또는 끝에서 발생할 수 있습니다.
내 생각은 줄의 시작 부분이나 콜론, 문자열 di=
, 콜론을 제외한 모든 문자, 콜론 또는 줄의 끝을 일치시키는 것입니다.
나는 "콜론을 제외한 모든 문자" 부분만 작동하게 만들었습니다.
일부 테스트:
echo "di=a;b:*.di=c;d:ddi=e;f" | sed "s/.*di=\([^:]*\):.*/\1/"
echo "ddi=a;b:di=c;d:*.di=e;f" | sed "s/.*di=\([^:]*\):.*/\1/"
echo "*.di=a;b:ddi=c;d:di=e;f" | sed "s/.*di=\([^:]*\):.*/\1/"
첫 번째 항목도 반환되어야 a;b
하고 두 번째 c;d
와 세 번째 항목도 반환되어야 e;f
하지만 이제 둘 다 반환됩니다 c;d
.
답변1
내 생각은 줄의 시작 부분이나 콜론을 일치시킨 다음 문자열 di=를 일치시키고 콜론을 제외한 모든 문자를 일치시킨 다음 콜론이나 줄의 끝을 일치시키는 것입니다.
예에서와 같이 "다음 콜론 또는 줄 끝"을 일치시킬 필요는 없습니다.
{
echo "di=a;b:*.di=c;d:ddi=e;f"
echo "ddi=a;b:di=c;d:*.di=e;f"
echo "*.di=a;b:ddi=c;d:di=e;f"
} | sed 's/\(^\|.*:\)di=\([^:]*\).*/\2/'
산출:
a;b
c;d
e;f
\(^\|.*:\)
줄의 시작 부분이나 뒤에 콜론이 오는 모든 문자와 일치합니다.
답변2
나는 이런 상황에 대해속이다:
앞쪽에 하나, 끝에 하나를 추가하여 특수한 경우를 제거하면 이제 항상 일치합니다.:a=foo:
그래서:
sed -e 's/^/:/' -e 's/$/:/' -e 's/.*:di=\([^:]*\):.*/\1/'
최적화될 수 있다
sed -e 's/^\(.*\)$/:\1:/' -e 's/.*:di=\([^:]*\):.*/\1/'
결과:
% echo "di=a;b:*.di=c;d:ddi=e;f" | sed -e 's/^/:/' -e 's/$/:/' -e 's/.*:di=\([^:]*\):.*/\1/'
a;b
% echo "ddi=a;b:di=c;d:*.di=e;f" | sed -e 's/^/:/' -e 's/$/:/' -e 's/.*:di=\([^:]*\):.*/\1/'
c;d
echo "*.di=a;b:ddi=c;d:di=e;f" | sed -e 's/^/:/' -e 's/$/:/' -e 's/.*:di=\([^:]*\):.*/\1/'
e;f
또 다른 치트는 줄 바꿈으로 변환하는 것입니다. 그런 다음 항상 아무 것도 없이 :
일치합니다.a=foo
:
tr : '\012' | sed -n 's/^di=//p'
답변3
Posixly는 표시된 대로 수행할 수 있습니다. 모든 콜론을 새 줄로 음역한 다음 di=가 나타날 때까지 선행 KV 쌍을 계속 잘라냅니다.
{
echo "di=a;b:*.di=c;d:ddi=e;f"
echo "ddi=a;b:di=c;d:*.di=e;f"
echo "*.di=a;b:ddi=c;d:di=e;f"
} \
| sed -n 'y/:/\n/;/^di=/!D;P'
di=a;b
di=c;d
di=e;f
답변4
awk
대신 sed
및 필드 구분 기호를 사용하여 각 레코드 :
를 =
반복하고 발견되면 다음 필드를 인쇄합니다 di
.
$ awk -F '[=:]' '{ for (i = 1; i < NF; ++i) if ($i == "di") { print $(i+1); next } }' file
a;b
c;d
e;f
마찬가지로, 레코드 구분 기호로 :
, =
및 개행 문자를 사용합니다.
$ awk -v RS='[=:\n]' '$0 == "di" { getline; print }' file
a;b
c;d
e;f
awk
RS
이는 다중 문자 값을 정규식으로 처리하는 경우에만 작동합니다 . 마지막 변형도 인쇄됩니다.각 di
그러한 값이 여러 개 있는 경우 원래 행의 각 값(첫 번째 변형은 다음을 next
호출하여 이를 방지합니다.