提取两个常量字符串之间的 WORD
Extract WORD between two constant strings
我有以下字符串
xml_srx_name="<name>SRX-NAME</name>"
我正在尝试打印 > 和 < 之间的文本
所以它会打印 SRX-NAME
我真的很接近,但这就是我得到的:>SRX-NAME< 这是我用这个命令能够实现的:
$ cat $xml_srx_name | awk '/SRX-NAME/ {print }' | grep -oPz "(?s)>.*?<" | tr '[=11=]' '\n'
Output:
>SRX-NAME<
input="test<hello>text"
rightpart=${input#*<} # remove prefix up to "<" (included)
output=${rightpart%>*} # remove suffix from ">" (included)
echo $output
或
在 bash 中使用 extglob,您可以一步完成:
shopt -s extglob
input='test<hello>heythere'
echo "${input//@(*<|>*)/}"
此处@(<|>) 匹配从开始到 < 字符的子字符串或从 > 到结束的子字符串。使用 // 我们将所有此类实例替换为空字符串。
你可以试试
- 最后加
| tr -d '<>'
- 使用
cat … |grep -o SRX-NAME
- 使用
cat … |cut -d \> -f 2 | cut -d \< -f 1
如果您最终得到一个使用 cat
、awk
、grep
和 tr
的复合命令,您可能有一个很好的 anti-pattern 示例. awk
一个人就够了:
$ xml_srx_name="<name>SRX-NAME</name>"
$ awk -F'<|>' '/SRX-NAME/ {print }' <<< "$xml_srx_name"
SRX-NAME
或 sed
:
$ sed '/SRX-NAME/s/.*>\(.*\)<.*//' <<< "$xml_srx_name"
SRX-NAME
您可以使用具有零长度断言的 GNU grep
,如下所示让 file.txt
内容为
xml_srx_name="<name>SRX-NAME</name>"
然后
grep -Po "(?<=\>).*(?=\<)" file.txt
输出
SRX-NAME
解释:在>
之后和<
.
之前找到0个或多个任意字符
(在 GNU grep 3.4 中测试)
您也可以仅使用 grep -oP
使用 perl 兼容的正则表达式:
<(name>)\K[^<]+(?=</)
或者写出完整的模式:
<name>\K[^<]+(?=</name>)
说明
<
字面匹配
(name>)\K
在组 1 中捕获 name>
[^<]+
匹配 <
以外的 1+ 个字符
(?=</)
正面前瞻,向右断言
示例
xml_srx_name="<name>SRX-NAME</name>"
grep -oP "<(name>)\K[^<]+(?=</)" <<< "$xml_srx_name"
输出
SRX-NAME
或将 sed
与捕获组一起使用:
xml_srx_name="<name>SRX-NAME</name>"
sed 's/.*<name>\([^<]\+\)<\/name>.*//' <<< "$xml_srx_name"
在每个 Unix 机器上的任何 shell 中使用任何 sed 或 awk:
$ xml_srx_name="<name>SRX-NAME</name>"
$ echo "$xml_srx_name" | awk -F'[<>]' '{print }'
SRX-NAME
$ echo "$xml_srx_name" | sed 's/.*>\(.*\)<.*//'
SRX-NAME
任何包含 SRX-NAME
的脚本都是毫无意义的,因为这意味着您已经知道要查找的字符串,因此可以只执行 echo 'SRX-NAME'
。
我有以下字符串
xml_srx_name="<name>SRX-NAME</name>"
我正在尝试打印 > 和 < 之间的文本 所以它会打印 SRX-NAME
我真的很接近,但这就是我得到的:>SRX-NAME< 这是我用这个命令能够实现的:
$ cat $xml_srx_name | awk '/SRX-NAME/ {print }' | grep -oPz "(?s)>.*?<" | tr '[=11=]' '\n'
Output:
>SRX-NAME<
input="test<hello>text"
rightpart=${input#*<} # remove prefix up to "<" (included)
output=${rightpart%>*} # remove suffix from ">" (included)
echo $output
或
在 bash 中使用 extglob,您可以一步完成:
shopt -s extglob
input='test<hello>heythere'
echo "${input//@(*<|>*)/}"
此处@(<|>) 匹配从开始到 < 字符的子字符串或从 > 到结束的子字符串。使用 // 我们将所有此类实例替换为空字符串。
你可以试试
- 最后加
| tr -d '<>'
- 使用
cat … |grep -o SRX-NAME
- 使用
cat … |cut -d \> -f 2 | cut -d \< -f 1
如果您最终得到一个使用 cat
、awk
、grep
和 tr
的复合命令,您可能有一个很好的 anti-pattern 示例. awk
一个人就够了:
$ xml_srx_name="<name>SRX-NAME</name>"
$ awk -F'<|>' '/SRX-NAME/ {print }' <<< "$xml_srx_name"
SRX-NAME
或 sed
:
$ sed '/SRX-NAME/s/.*>\(.*\)<.*//' <<< "$xml_srx_name"
SRX-NAME
您可以使用具有零长度断言的 GNU grep
,如下所示让 file.txt
内容为
xml_srx_name="<name>SRX-NAME</name>"
然后
grep -Po "(?<=\>).*(?=\<)" file.txt
输出
SRX-NAME
解释:在>
之后和<
.
(在 GNU grep 3.4 中测试)
您也可以仅使用 grep -oP
使用 perl 兼容的正则表达式:
<(name>)\K[^<]+(?=</)
或者写出完整的模式:
<name>\K[^<]+(?=</name>)
说明
<
字面匹配(name>)\K
在组 1 中捕获 [^<]+
匹配<
以外的 1+ 个字符
(?=</)
正面前瞻,向右断言
name>
示例
xml_srx_name="<name>SRX-NAME</name>"
grep -oP "<(name>)\K[^<]+(?=</)" <<< "$xml_srx_name"
输出
SRX-NAME
或将 sed
与捕获组一起使用:
xml_srx_name="<name>SRX-NAME</name>"
sed 's/.*<name>\([^<]\+\)<\/name>.*//' <<< "$xml_srx_name"
在每个 Unix 机器上的任何 shell 中使用任何 sed 或 awk:
$ xml_srx_name="<name>SRX-NAME</name>"
$ echo "$xml_srx_name" | awk -F'[<>]' '{print }'
SRX-NAME
$ echo "$xml_srx_name" | sed 's/.*>\(.*\)<.*//'
SRX-NAME
任何包含 SRX-NAME
的脚本都是毫无意义的,因为这意味着您已经知道要查找的字符串,因此可以只执行 echo 'SRX-NAME'
。