用斜线捕获模式后的单词

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 前面)。我不在乎 awkgrepsed、...

使用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 grepoP 选项。负责打印精确匹配和启用 PCRE 正则表达式。在主程序中,使用正则表达式 ^.*? /CLIENT_LOGIN:\K(\S+): 这意味着使用从值开始到 /CLIENT_LOGIN: 的惰性匹配来匹配第一次出现的字符串。然后使用 \K 选项忘记到目前为止匹配的值,这样我们就可以只打印所需的值,后面跟着 \S+,这意味着在任何 space 出现之前匹配所有 NON-Spaces。



第二个解决方案: 使用 awkmatch 函数及其 split打印所需值的函数。

awk '
match([=11=],/\/CLIENT_LOGIN:[^[:space:]]+/){
  split(substr([=11=],RSTART,RLENGTH),arr,":")
  print arr[2]
}
' Input_file


第三个解决方案: 使用 GNU awkFPAT 选项请尝试以下解决方案。简单的解释是,将 FPAT 设置为 /CLIENT_LOGIN:,然后是所有 non-spaces 值。在 awk 的主程序中,使用 sub: 之前的所有内容替换为第一个字段的 NULL,然后打印第一个字段。

awk -v FPAT='/CLIENT_LOGIN:[^[:space:]]+' '{sub(/.*:/,"",);print }'  Input_file