키 값 추출

키 값 추출

나는 어떤 텍스트라도 전달하고 문자열에서 키 값을 추출할 수 있는 간단한 스크립트를 원합니다.

XML이나 JSON 입력은 물론 로그의 텍스트와 같은 잘못된 형식의 입력도 수용할 수 있을 만큼 유연하길 원합니다.

test예를 들어, 다음 입력 중 하나가 주어지면 키 값을 추출할 수 있어야 합니다 .

예를 들어

$ echo "test:5 hi there" | extract_key_value test

결과가 나와야 한다

5

나는 그것이 무엇으로 쓰여졌는지 상관하지 않으므로 node, ruby ​​등은 나에게 괜찮지만 이식성(Linux/osx)은 괜찮습니다 ;-)

1을 입력하세요

this is test:5 i saw a value

2를 입력하세요

this is test:'another value' i saw a value

3을 입력하세요

this is test=5 i saw a value

4를 입력하세요

test='a string value here'

5를 입력하세요

my data
on line 2 test='a string value here'
more data

이에 대한 나의 빠른 해킹은 다음과 같습니다. 크게 개선될 수 있다고 생각하며 어딘가에서 해결해야 한다고 생각합니다!

키 값 추출

#!/usr/bin/env bash

function show_help()
{
  IT=$(cat <<EOF
  
  Helps you extract a key value from a string, typically a log msg

  usage: key {keyBeginDelim} {keyEndDelim}

  e.g. given "asd f asdf asdf test=easy asdf me=you" as input

  extract_key_value test        
  => returns easy
EOF
)
  echo "$IT"
  exit
}

if [ "$1" == "help" ]
then
  show_help
fi
if [ -z "$1" ]
then
  show_help
fi

INPUT=$(cat -)
KEY="$1"

function getVal()
{
  DELIM1="$1"
  DELIM2="$2"
  echo "$INPUT" | awk -F "$DELIM1" '{print $2}' | awk -F "$DELIM2" '{print $1}'
}

# Try whatever the user passed in or defaults for delims
if [ -n "$2" ]
then
  IT=$(getVal "$2" "$3")
fi

# Try other use cases
if [ -z "$IT" ]
then
  IT=$(getVal "$KEY:'" "'")
fi
if [ -z "$IT" ]
then
  IT=$(getVal "$KEY='" "'")
fi
if [ -z "$IT" ]
then
  IT=$(getVal "$KEY=\"" "\"")
fi
if [ -z "$IT" ]
then
  IT=$(getVal "$KEY:\"" "\"")
fi
if [ -z "$IT" ]
then
  IT=$(getVal "$KEY:" " ")
fi
if [ -z "$IT" ]
then
  IT=$(getVal "$KEY=" " ")
fi
if [ -z "$IT" ]
then
  IT=$(getVal "$KEY=" ";")
fi
if [ -z "$IT" ]
then
  IT=$(getVal "$KEY:" ";")
fi

echo "$IT"

답변1

그리고 pcregrep:

extract_key_value() {
  pcregrep -Mo1 "(?sx)
   (?:
       \Q$1\E      # key literally
     | \"\Q$1\E\"  # same in double quotes
     | '\Q$1\E'    # same in single quotes
   )
   [=:]
   (?|  # branch reset
       '(.*?)'
     | \"(.*?)\"
     | ([^\"'\s]+)
   )"
}
  • -M:여러 줄 일치( test:'foo\nbar'... 허용)
  • -o1: 첫 번째 캡처 그룹과 일치하는 텍스트를 출력합니다(아래 참조).분기 재설정).
  • (?sx): 활성화 s플래그( .새 줄에도 일치) 및 x플래그(주석 형식이 있는 여러 줄 허용)
  • \Q$1\E(함수의 첫 번째 매개변수)는 $1문자 그대로 받아들여야 합니다. 그 자체를 포함하지 않는다고 가정합니다 \E. ksh93과 유사한 셸에서는 교체를 통해 이 문제를 해결할 bash수 있습니다 .$1${1//\\E/\\E\\\\E\\Q}
  • (?|.(.).|.(.).)지점 재설정. 캡처 그룹의 번호는 각 이후 1부터 시작하므로 |교대 -o1로 일치하는 첫 번째 캡처 그룹이 반환됩니다.
  • '.*?'. .*?예, 탐욕스럽지 않은 변형 .*이므로 to 이후의 첫 번째 변형 '.*'과 일치합니다 .''
  • \s: 모든 공백 문자.

\x이것은 json 인코딩, 따옴표 안에 따옴표 삽입(언어에 따라 다름)과 같은 특수한 경우를 해결하려고 시도하지 않습니다 . 양쪽에 :공백을 허용하지 않습니다 =. 필요한 경우 이 모든 문제를 해결할 수 있습니다. 이는 처리하려는 입력의 정확한 유형에 따라 달라집니다.

답변2

grep의 예:

function extract_key_value() {
    egrep -o "$1[:=]['\"[:alnum:]]+" | egrep -o "['\"[:alnum:]]+$" | egrep -o "[[:alnum:]]+"
}
echo -e "on line 1\ntest:123 asasas\non line 3\ntest='abc'\non line 5" | extract_key_value test

관련 정보