私は任意のテキストを渡し、文字列からキー値を抽出するための簡単なスクリプトが欲しいです。
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