segment.bytes
우리는 매개변수 와 해당 값을 캡처하고 싶습니다.
예
echo "$info" | grep "segment.bytes"
{"version":1,"config":{"segment.bytes":"10737555","retention.bytes":"104857600"}}
내 생각은 값을 포함하지만 값을 포함하지 않는 모든 단어를 제거 segment.bytes
하고 제거하는 것입니다.segment.bytes
큰따옴표
예상 결과의 예
echo "$info" | grep "segment.bytes" | ......
segment.bytes:10737555
나는 이것을 시도 할 것이다
echo "$info" | grep "segment.bytes" | sed s'/"/ /g' | sed 's/^.*segment.bytes/segment.bytes/' | awk '{print $1":"$3}
나는 얻다
segment.bytes:10737555
하지만 가치를 얻는 결과가 매우 높기 때문에 내 접근 방식이 위험할 수 있다고 생각합니다.예민한중요한 것은 잘못된 결과를 얻을 수도 있다는 것입니다.비참한
더 신뢰할 수 있는 다른 옵션이 있으면 좋겠습니다.
답변1
$info
다음 호출을 통해 sed
변수를 파이프 할 수 있습니다 .
echo "$info" | sed -E '/"segment\.bytes"/s/.*"(segment\.bytes)":"([^"]+)".*/\1:\2/'
패턴이 있는 행을 찾고 문자열 "segment.bytes"
과 segment.bytes
대괄호 안의 다음 문자열( "
단순화를 위해 "그러나"로 정의됨)을 캡처 그룹 1과 2로 추출하고 "캡처 그룹 1", ":" 및 "캡처 그룹"을 인쇄합니다. 2".
(확장 정규식을 활성화하는 옵션은 sed
버전에 따라 다를 수 있습니다. -E
이제 POSIX 표준이며 현재 GNU, MacOS 및 BSD에서 작동 sed
하지만 실패할 경우 ERE 페이지 활성화 방법에 대한 매뉴얼을 확인하세요.)
좀 더 선택적으로 시도해 보세요.
sed -E '/"segment\.bytes":"[0-9]+"/s/.*"(segment\.bytes)":"([0-9]+)".*/\1:\2/'
행 검색 및 값 캡처 부분에서는 정수 값만 허용합니다.
답변2
grep
전화하기 전에 전화할 필요가 없습니다 sed
.
$ echo "$info"
foo
{"version":1,"config":{"segment.bytes":"10737555","retention.bytes":"104857600"}}
bar
$ echo "$info" | sed -n 's/.*"\(segment\.bytes\)":"\([^"]*\)".*/\1:\2/p'
segment.bytes:10737555
또는 전체 행에 대한 매우 구체적인 일치의 경우 잘못된 일치 가능성이 거의 불가능하지만 분명히 입력 형식의 변경에 더 민감합니다.
$ echo "$info" |
sed -n 's/^{"version":[0-9][0-9]*,"config":{"\(segment\.bytes\)":"\([0-9][0-9]*\)","retention\.bytes":"[0-9][0-9]*"}}$/\1:\2/p'
segment.bytes:10737555
위의 내용은 모든 sed에 적용됩니다.
답변3
안전하고 신뢰할 수 있는 방법은 jq
유틸리티를 사용하는 것입니다.
$ echo "$info" \
| grep -F '"segment.bytes"' \
| jq -r '.config | "segment.bytes:" + ."segment.bytes"'
큰 타격:
parameter substitutions
왼쪽과 오른쪽 끝에서 잘라내고 세그먼트.바이트 속성 값을 추출합니다.
name="segment.bytes"
var=${info#*\"${name}\":\"}
printf "%s:%s\n" "$name" "${var%%\"*}"'
또 다른 방법은 먼저 tye 정보 문자열을 중괄호의 쉼표와 줄 바꿈으로 분할하여 grep이 해당 작업을 수행하고 grep의 출력에서 큰따옴표를 제거할 수 있도록 하는 것입니다.
$ echo "$info" \
| tr '{,}' '[\n*]' \
| grep '^"segment\.bytes"' \
| tr -d \"
JSON 모듈과 함께 Perl 사용
$ echo "$line" | grep -F '"segment.bytes"' \
| perl -MJSON -lne '$,=":";
my $k = "segment.bytes";
print $k, decode_json($_)->{config}{$k};
'
JSON 모듈을 사용할 수 없는 경우에도 이 작업을 수행할 수 있습니다. 여기서는 먼저 sed를 사용하여 유효한 Perl 코드를 생성한 다음 do 문을 통해 Perl에서 이를 구현합니다. 그러면 json 객체 $j는 우리가 원하는 키를 추출할 수 있는 해시 참조입니다.
$ echo "$info" \
| sed \
-e '/"segmen\.bytes"/!d' \
-e 'y/:/,/;s/.*/$j=&;/' \
> ./foo.json
$ perl -I. -le '$,=":";
my $name = "segment.bytes";
do "foo.json" or die $!;
print $name, $j->{config}{$name};
'
awk와 sed는 설명이 필요 없습니다.
$ echo "$info" | grep -F segment.bytes \
| awk -F '"segment\\.bytes":"' '
{
t = $2
sub(/".*/, "", t)
$0 = FS t
gsub(/["\\]/, "")
}1'
$ echo "$info" | grep -F segment.bytes \
| sed -ne '
y/{,}/\n\n\n/
/^"segment.bytes"/!D
s/"//g;P
'
답변4
다음 awk 명령을 사용할 수 있습니다
echo "$info"|awk -F "," '/segment.bytes/{for(i=1;i<=NF;i++){if($i ~ /segment/){gsub("\"","",$i);print $i }}}'| sed "s/.*{//g"
산출
segment.bytes:10737555