仅对字符串的 select 中间部分使用 sed
Only using sed to select mid portion on a string
我有包含这样文本的文件
4539 DECK AAA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABC
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABD
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999
我想从中提取一个 selected 端口。所以输出必须是这样的。没有前后空格制表符
AAA
ABC
ABA
ABD
我用过这个,但它 select 整行在文本之后。有没有办法只使用 sed。对任何其他解决方案不感兴趣
sed "s/.*DECK[[:blank:]](.[A-Z])*/\1/"
您可以使用
sed -n '/.*DECK[[:blank:]]*\([[:upper:]]*\).*/s///p'
详情:
n
- 抑制默认行输出
/.*DECK[[:blank:]]*\([[:upper:]]*\).*/
- 零个或多个字符,DECK
然后匹配零个或多个水平空格,然后消耗零个或多个大写字母并放入第 1 组,然后是其余的字符串(此处为行)匹配
s///p
- 上面模式中的匹配项(空模式告诉 sed 使用之前使用的模式)被第 1 组值替换,并且只有这个值是 p
rinted .
#!/bin/bash
s='4539 DECK AAA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABC
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABD
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999'
sed -n '/.*DECK[[:blank:]]*\([A-Z]*\).*/s///p' <<< "$s"
输出:
AAA
ABC
ABA
ABD
第一个解决方案: 使用您显示的示例,尝试在此处使用以下 sed
。使用 -E
和 -n
选项分别启用 ERE 和停止打印行。然后匹配从 start 到 till DECK 的所有内容,然后是 space 然后创建第一个反向引用以在行尾使用大写字母;然后在替换部分用第一个反向引用值替换它。
sed -E -n 's/.*DECK[[:space:]]+([A-Z]+$)//p' Input_file
第二个解决方案: 使用 awk
你可以尝试下面的程序,用显示的示例编写和测试。简单的解释是,使用 awk
的 match
函数来匹配正则表达式 DECK [A-Z]+
查找 sting DECK 后跟 space 和大写字母,然后只打印所需的输出.
awk 'match([=11=],/DECK [A-Z]+/){print substr([=11=],RSTART+5,RLENGTH-5)}' Input_file
第三个解决方案: 使用 GNU grep
尝试以下一次。首先使用 -oP
选项精确匹配匹配的正则表达式并分别启用 ERE。匹配所有内容直到 DECK space 并用 \K 忘记它然后匹配大写字母并打印它们。
grep -oP '.*DECK[[:space:]]*\K[A-Z]+' Input_file
我有包含这样文本的文件
4539 DECK AAA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABC
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABD
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999
我想从中提取一个 selected 端口。所以输出必须是这样的。没有前后空格制表符
AAA
ABC
ABA
ABD
我用过这个,但它 select 整行在文本之后。有没有办法只使用 sed。对任何其他解决方案不感兴趣
sed "s/.*DECK[[:blank:]](.[A-Z])*/\1/"
您可以使用
sed -n '/.*DECK[[:blank:]]*\([[:upper:]]*\).*/s///p'
详情:
n
- 抑制默认行输出/.*DECK[[:blank:]]*\([[:upper:]]*\).*/
- 零个或多个字符,DECK
然后匹配零个或多个水平空格,然后消耗零个或多个大写字母并放入第 1 组,然后是其余的字符串(此处为行)匹配s///p
- 上面模式中的匹配项(空模式告诉 sed 使用之前使用的模式)被第 1 组值替换,并且只有这个值是p
rinted .
#!/bin/bash
s='4539 DECK AAA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABC
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABA
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999 4539 DECK ABD
OO-99999999-99999999-99999999-99999999 -99999999-99999999 259800
259800 259800-99999999-99999999'
sed -n '/.*DECK[[:blank:]]*\([A-Z]*\).*/s///p' <<< "$s"
输出:
AAA
ABC
ABA
ABD
第一个解决方案: 使用您显示的示例,尝试在此处使用以下 sed
。使用 -E
和 -n
选项分别启用 ERE 和停止打印行。然后匹配从 start 到 till DECK 的所有内容,然后是 space 然后创建第一个反向引用以在行尾使用大写字母;然后在替换部分用第一个反向引用值替换它。
sed -E -n 's/.*DECK[[:space:]]+([A-Z]+$)//p' Input_file
第二个解决方案: 使用 awk
你可以尝试下面的程序,用显示的示例编写和测试。简单的解释是,使用 awk
的 match
函数来匹配正则表达式 DECK [A-Z]+
查找 sting DECK 后跟 space 和大写字母,然后只打印所需的输出.
awk 'match([=11=],/DECK [A-Z]+/){print substr([=11=],RSTART+5,RLENGTH-5)}' Input_file
第三个解决方案: 使用 GNU grep
尝试以下一次。首先使用 -oP
选项精确匹配匹配的正则表达式并分别启用 ERE。匹配所有内容直到 DECK space 并用 \K 忘记它然后匹配大写字母并打印它们。
grep -oP '.*DECK[[:space:]]*\K[A-Z]+' Input_file