如何使用'sed'
从一行中提取3个或更多单独的文本我有以下一行:
echo <MX><[Mike/DOB-029/Post-555/Male]><MX>
到目前为止,我可以通过
提取'DOB-029'sed -n 's/.*\(DOB-[0-9]*\).*/\1/p'
但我没有收到其他文字,如姓名或帖子。
我的预期输出应为 Mike DOB-029 后555
被修改
假设我在文件中有一个列表,我想从整个列表中提取特定的文本/ ID并将其保存到.txt文件
答案 0 :(得分:3)
sed 's/.*[\(.*\).\(DOB-[0-9]*\).\(Post-[0-9]*\).*/\1 \2 \3/'
应该做到这一点!
\(
和\)
之间的部分是捕获的字符串,可以使用\i
并使用i
组的索引来调用。
自定义脚本:
#! /bin/bash
fields=${1:-123}
file='/path/to/input'
name=$(sed 's/.*\[\([^\/]*\)\/.*/\1/' $file)
dob=$(sed 's/.*\(DOB-[0-9]*\).*/\1/' $file)
post=$(sed 's/.*\(Post-[0-9]*\).*/\1/' $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'或您喜欢的任何组合。
<强> STDIN 强>
如果要从stdin读取,请使用以下脚本:
#! /usr/bin/env bash
line=$(cat /dev/stdin)
fields=${1:-123}
name=$(echo $line | sed 's/.*\[\([^\/]*\)\/.*/\1/')
dob=$(echo $line | sed 's/.*\(DOB-[0-9]*\).*/\1/')
post=$(echo $line | sed 's/.*\(Post-[0-9]*\).*/\1/')
[[ $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
答案 1 :(得分:3)
awk:
的解决方案echo "<MX><[Mike/DOB-029/Post-555/Male]><MX>" | awk -F[/[] '{print $2, $3, $4}'
我们将分隔符设置为/
或[
(-F[/[]
)。然后我们只打印$2, $3 and $4
字段2nd, 3rd and 4th fields
。
使用 sed:
echo "<MX><[Mike/DOB-029/Post-555/Male]><MX>" | sed 's/\(^.*\[\)\(.*\)\(\/[^/]*$\)/\2/; s/\// /g'
答案 2 :(得分:1)
使用bash替换内置。
line="<MX><[Mike/D0B-029/Post-555/Male]><MX>";
linel=${line/*[/}; liner=${linel%\/*}; echo ${liner//\// }