如何在 zshell 中以关键字拆分字符串并保存结果?
How can I split a string at a keyword in zshell and save the result?
我是 zshell 的新手,正在尝试使用关键字作为分隔符来拆分字符串。输出来自 netfilter,并不总是在固定位置,所以我需要根据我感兴趣的关键字进行拆分。
我找到了一种可行的方法,但似乎应该有一种更简单的方法来实现。有什么想法吗?
line="[Thu Jul 23 12:29:50 2015] IN=eth0 OUT= SRC=10.1.1.17 DST=10.101.11.1 PROTO=TCP SPT=46286 DPT=1113 SYN URGP=0 "
# this returns a substring starting from 'SRC=' to the end
tmp=${(MS)line##SRC=*}
# use the first element returned in the substring
src=$tmp[(w)1]
echo "src is $src"
你几乎可以把 line
变成一个关联数组,但是 key=value
项看起来太不规则了,因为有时 =
会丢失,有时 value
也没有。因此,一种方法是简单地将整个 line
拆分为空格并将其放入数组的元素中。目前尚不清楚输出的顺序如何,但如果您可以指望所需的键存在并且顺序一致,一种方法是:
ary=( ${(s. .)line} ) # split on spaces, storing into array
print $ary[8]
SRC=10.1.1.17
现在您可以通过索引获取任何键值。您也可以使用此数组作为真正关联数组的起点。
您可能想先删除日期戳内容 ([...]
)。
要解析单个关键字,我会使用正则表达式匹配 =~
conditional operator。
if [[ $line =~ [[:space:]]SRC=[^[:space:]]+ ]]; then
echo src is $MATCH[6,$#MATCH]
else
echo >&2 No SRC=
fi
为了解析多个关键字,我使用 parameter expansion constructs 拆分字符串减去空白处的时间戳并将输出存储在关联数组中。
timestamp=${${line%%\]*}##*\[}
typeset -A info
for x in ${=line#*\]}; do
if [[ $x = *=* ]]; then
info[${x%%=*}]=${x#*=}
else
info[$x]=
fi
done
echo src is $info[SRC]
我是 zshell 的新手,正在尝试使用关键字作为分隔符来拆分字符串。输出来自 netfilter,并不总是在固定位置,所以我需要根据我感兴趣的关键字进行拆分。
我找到了一种可行的方法,但似乎应该有一种更简单的方法来实现。有什么想法吗?
line="[Thu Jul 23 12:29:50 2015] IN=eth0 OUT= SRC=10.1.1.17 DST=10.101.11.1 PROTO=TCP SPT=46286 DPT=1113 SYN URGP=0 "
# this returns a substring starting from 'SRC=' to the end
tmp=${(MS)line##SRC=*}
# use the first element returned in the substring
src=$tmp[(w)1]
echo "src is $src"
你几乎可以把 line
变成一个关联数组,但是 key=value
项看起来太不规则了,因为有时 =
会丢失,有时 value
也没有。因此,一种方法是简单地将整个 line
拆分为空格并将其放入数组的元素中。目前尚不清楚输出的顺序如何,但如果您可以指望所需的键存在并且顺序一致,一种方法是:
ary=( ${(s. .)line} ) # split on spaces, storing into array
print $ary[8]
SRC=10.1.1.17
现在您可以通过索引获取任何键值。您也可以使用此数组作为真正关联数组的起点。
您可能想先删除日期戳内容 ([...]
)。
要解析单个关键字,我会使用正则表达式匹配 =~
conditional operator。
if [[ $line =~ [[:space:]]SRC=[^[:space:]]+ ]]; then
echo src is $MATCH[6,$#MATCH]
else
echo >&2 No SRC=
fi
为了解析多个关键字,我使用 parameter expansion constructs 拆分字符串减去空白处的时间戳并将输出存储在关联数组中。
timestamp=${${line%%\]*}##*\[}
typeset -A info
for x in ${=line#*\]}; do
if [[ $x = *=* ]]; then
info[${x%%=*}]=${x#*=}
else
info[$x]=
fi
done
echo src is $info[SRC]