如何使用 sed 从字符串中提取多个文本和数字?

How to extract multiple text and numbers from a string using sed?

如何使用 'sed'

从一行中提取 3 个或更多单独的文本

我有以下行:

echo <MX><[Mike/DOB-029/Post-555/Male]><MX>

到目前为止,我可以通过

提取'DOB-029'
sed -n 's/.*\(DOB-[0-9]*\).*//p'

但我没有收到其他文本,例如名称或 post。

我的预期输出应该是 Mike DOB-029 Post-555

已编辑

假设我在文件中有一个列表,我想从整个列表中提取特定的 text/IDs 并将其保存到 .txt 文件

sed 's/.*[\(.*\).\(DOB-[0-9]*\).\(Post-[0-9]*\).*/ /' 应该可以解决问题![​​=19=]

\(\) 之间的部分是捕获的字符串,可以使用 \ii 组索引调用。

自定义使用的脚本:

#! /bin/bash


fields=${1:-123}
file='/path/to/input'

name=$(sed 's/.*\[\([^\/]*\)\/.*//' $file)
dob=$(sed 's/.*\(DOB-[0-9]*\).*//' $file)
post=$(sed 's/.*\(Post-[0-9]*\).*//' $file)

[[ $fields =~ .*1.* ]] && output=$name
[[ $fields =~ .*2.* ]] && output="$output $dob"
[[ $fields =~ .*3.* ]] && output="$output $post"

echo $output

file 变量中使用您要解析的行设置文件(我可以添加更多功能,例如将文件作为参数提供,或者如果您愿意,可以从更大的文件中获取它)。并使用一个 int 参数执行脚本,如果这个 int 包含'1',它将显示名称,如果 2,它将显示 DOB,3 将输出 post 信息。你可以结合起来,例如“123”或“32”或您喜欢的任何组合。

标准输入

如果要从标准输入读取,请使用以下脚本:

#! /usr/bin/env bash

line=$(cat /dev/stdin)

fields=${1:-123}

name=$(echo $line | sed 's/.*\[\([^\/]*\)\/.*//')
dob=$(echo $line | sed 's/.*\(DOB-[0-9]*\).*//')
post=$(echo $line | sed 's/.*\(Post-[0-9]*\).*//')

[[ $fields =~ .*1.* ]] && output=$name
[[ $fields =~ .*2.* ]] && output="$output $dob"
[[ $fields =~ .*3.* ]] && output="$output $post"

echo $output

用法示例:

$ chmod +x script.sh
$ echo '<MX><[Mike/DOB-029/Post-555/Male]><MX>' | ./script.sh 123
Mike DOB-029 Post-555
$ echo '<MX><[Mike/DOB-029/Post-555/Male]><MX>' | ./script.sh 12
Mike DOB-029
$ echo '<MX><[Mike/DOB-029/Post-555/Male]><MX>' | ./script.sh 32
DOB-029 Post-555
$ echo '<MX><[Mike/DOB-029/Post-555/Male]><MX>' | ./script.sh 
Mike DOB-029 Post-555

使用 awk 的解决方案:

echo "<MX><[Mike/DOB-029/Post-555/Male]><MX>" | awk -F[/[] '{print , , }'

我们将分隔符设置为/[-F[/[])。然后我们只打印字段 , and 分别是 2nd, 3rd and 4th fields.

使用 sed:

echo "<MX><[Mike/DOB-029/Post-555/Male]><MX>" | sed 's/\(^.*\[\)\(.*\)\(\/[^/]*$\)//; s/\// /g'

使用 bash 替换内置函数。

line="<MX><[Mike/D0B-029/Post-555/Male]><MX>"; 
linel=${line/*[/}; liner=${linel%\/*}; echo ${liner//\// }