Bash-从任意文本中按名称提取键值?

布莱德公园

我想要一个简单的脚本,该脚本可以让我传递任何文本,并且可以从字符串中提取键的值。

我希望它具有灵活性,可以接受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

接下来是我的快速破解,我觉得可以大大改善,并且认为应该在某个地方解决它!

extract_key_value

#!/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"
斯蒂芬·查泽拉斯(Stephane Chazelas)

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的shell中bash,您可以替换$1${1//\\E/\\E\\\\E\\Q}来解决该问题。
  • (?|.(.).|.(.).)分支重置。捕获组的编号从1后面开始|,因此-o1将返回第一个匹配的捕获组。
  • '.*?'.*?是的非贪婪变体.*,因此'.*'将从匹配'到第一个'
  • \s:任何空白字符。

这不会尝试解决一些极端的情况,例如\xjson中编码,将引号嵌入引号中(根据语言的不同而有所不同)。:或的任何一侧都不允许有空格=如果需要,可以解决所有这些问题。这将取决于您要处理的确切输入的类型。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章