用斜线捕获模式后的单词
Capture word after pattern with slash
我想从中提取 word1:
something /CLIENT_LOGIN:word1 something else
我想提取匹配模式后的第一个词/CLIENT_LOGIN:
。
没有斜线,像这样的东西可以工作:
A=something /CLIENT_LOGIN:word1 something else
B=$(echo $A | awk ' == "CLIENT_LOGIN" { print }' FS=":")
虽然有斜线,但我无法让它工作(我尝试将 /
和 \/
放在 CLIENT_LOGIN
前面)。我不在乎 awk
、grep
、sed
、...
使用sed
:
s='=something /CLIENT_LOGIN:word1 something else'
sed -E 's~.* /CLIENT_LOGIN:([^[:blank:]]+).*~~' <<< "$s"
word1
详情:
- 我们在
sed
中使用 ~
作为正则表达式分隔符
/CLIENT_LOGIN:([^[:blank:]]+)
匹配 /CLIENT_LOGIN:
后跟在组 #1 中捕获的 1+ non-whitespace 个字符
.*
双方匹配我们匹配前后的文字
用于替换以将第一组的捕获值放回输出
修复你的 awk
命令,你可以使用
A="/CLIENT_IPADDR:23.4.28.2 /CLIENT_LOGIN:xdfmb1d /MXJ_C"
B=$(echo "$A" | awk 'match([=10=],/\/CLIENT_LOGIN:[^[:space:]]+/){print substr([=10=],RSTART+14,RLENGTH-14)}')
查看 online demo 产生 xdfmb1d
。 详情:
\/CLIENT_LOGIN:
- /CLIENT_LOGIN:
字符串
[^[:space:]]+
- 一个或多个 non-whitespace 个字符
上面的模式是 awk
搜索的内容,一旦匹配,/CLIENT_LOGIN:
之后的匹配值部分将使用 substr([=18=],RSTART+14,RLENGTH-14)
“提取”(其中 14 是长度/CLIENT_LOGIN:
字符串)。
执行正则表达式匹配并在 BASH_REMATCH[]
:
中捕获结果字符串
$ regex='.*/CLIENT_LOGIN:([^[:space:]]*).*'
$ A='something /CLIENT_LOGIN:word1 something else'
$ unset B
$ [[ "${A}" =~ $regex ]] && B="${BASH_REMATCH[1]}"
$ echo "${B}"
word1
验证 B
如果我们没有找到我们的匹配项仍然未定义:
$ A='something without the desired string'
$ unset B
$ [[ "${A}" =~ $regex ]] && B="${BASH_REMATCH[1]}"
$ echo "${B}"
<<<=== nothing output
第一个解决方案:使用您显示的示例,请尝试遵循 GNU grep
解决方案。
grep -oP '^.*? /CLIENT_LOGIN:\K(\S+)' Input_file
解释: 简单的解释就是,使用 GNU grep
的 o
和 P
选项。负责打印精确匹配和启用 PCRE 正则表达式。在主程序中,使用正则表达式 ^.*? /CLIENT_LOGIN:\K(\S+)
: 这意味着使用从值开始到 /CLIENT_LOGIN:
的惰性匹配来匹配第一次出现的字符串。然后使用 \K
选项忘记到目前为止匹配的值,这样我们就可以只打印所需的值,后面跟着 \S+
,这意味着在任何 space 出现之前匹配所有 NON-Spaces。
第二个解决方案: 使用 awk
的 match
函数及其 split
打印所需值的函数。
awk '
match([=11=],/\/CLIENT_LOGIN:[^[:space:]]+/){
split(substr([=11=],RSTART,RLENGTH),arr,":")
print arr[2]
}
' Input_file
第三个解决方案: 使用 GNU awk
的 FPAT
选项请尝试以下解决方案。简单的解释是,将 FPAT
设置为 /CLIENT_LOGIN:
,然后是所有 non-spaces 值。在 awk
的主程序中,使用 sub
将 :
之前的所有内容替换为第一个字段的 NULL,然后打印第一个字段。
awk -v FPAT='/CLIENT_LOGIN:[^[:space:]]+' '{sub(/.*:/,"",);print }' Input_file
我想从中提取 word1:
something /CLIENT_LOGIN:word1 something else
我想提取匹配模式后的第一个词/CLIENT_LOGIN:
。
没有斜线,像这样的东西可以工作:
A=something /CLIENT_LOGIN:word1 something else
B=$(echo $A | awk ' == "CLIENT_LOGIN" { print }' FS=":")
虽然有斜线,但我无法让它工作(我尝试将 /
和 \/
放在 CLIENT_LOGIN
前面)。我不在乎 awk
、grep
、sed
、...
使用sed
:
s='=something /CLIENT_LOGIN:word1 something else'
sed -E 's~.* /CLIENT_LOGIN:([^[:blank:]]+).*~~' <<< "$s"
word1
详情:
- 我们在
sed
中使用 /CLIENT_LOGIN:([^[:blank:]]+)
匹配/CLIENT_LOGIN:
后跟在组 #1 中捕获的 1+ non-whitespace 个字符
.*
双方匹配我们匹配前后的文字用于替换以将第一组的捕获值放回输出
~
作为正则表达式分隔符
修复你的 awk
命令,你可以使用
A="/CLIENT_IPADDR:23.4.28.2 /CLIENT_LOGIN:xdfmb1d /MXJ_C"
B=$(echo "$A" | awk 'match([=10=],/\/CLIENT_LOGIN:[^[:space:]]+/){print substr([=10=],RSTART+14,RLENGTH-14)}')
查看 online demo 产生 xdfmb1d
。 详情:
\/CLIENT_LOGIN:
-/CLIENT_LOGIN:
字符串[^[:space:]]+
- 一个或多个 non-whitespace 个字符
上面的模式是 awk
搜索的内容,一旦匹配,/CLIENT_LOGIN:
之后的匹配值部分将使用 substr([=18=],RSTART+14,RLENGTH-14)
“提取”(其中 14 是长度/CLIENT_LOGIN:
字符串)。
执行正则表达式匹配并在 BASH_REMATCH[]
:
$ regex='.*/CLIENT_LOGIN:([^[:space:]]*).*'
$ A='something /CLIENT_LOGIN:word1 something else'
$ unset B
$ [[ "${A}" =~ $regex ]] && B="${BASH_REMATCH[1]}"
$ echo "${B}"
word1
验证 B
如果我们没有找到我们的匹配项仍然未定义:
$ A='something without the desired string'
$ unset B
$ [[ "${A}" =~ $regex ]] && B="${BASH_REMATCH[1]}"
$ echo "${B}"
<<<=== nothing output
第一个解决方案:使用您显示的示例,请尝试遵循 GNU grep
解决方案。
grep -oP '^.*? /CLIENT_LOGIN:\K(\S+)' Input_file
解释: 简单的解释就是,使用 GNU grep
的 o
和 P
选项。负责打印精确匹配和启用 PCRE 正则表达式。在主程序中,使用正则表达式 ^.*? /CLIENT_LOGIN:\K(\S+)
: 这意味着使用从值开始到 /CLIENT_LOGIN:
的惰性匹配来匹配第一次出现的字符串。然后使用 \K
选项忘记到目前为止匹配的值,这样我们就可以只打印所需的值,后面跟着 \S+
,这意味着在任何 space 出现之前匹配所有 NON-Spaces。
第二个解决方案: 使用 awk
的 match
函数及其 split
打印所需值的函数。
awk '
match([=11=],/\/CLIENT_LOGIN:[^[:space:]]+/){
split(substr([=11=],RSTART,RLENGTH),arr,":")
print arr[2]
}
' Input_file
第三个解决方案: 使用 GNU awk
的 FPAT
选项请尝试以下解决方案。简单的解释是,将 FPAT
设置为 /CLIENT_LOGIN:
,然后是所有 non-spaces 值。在 awk
的主程序中,使用 sub
将 :
之前的所有内容替换为第一个字段的 NULL,然后打印第一个字段。
awk -v FPAT='/CLIENT_LOGIN:[^[:space:]]+' '{sub(/.*:/,"",);print }' Input_file