SED 命令替换
SED Command Replacement
假设我有一个带有警告的文件。新行中的每个警告的 ID 仅包含 3 个大写字母后跟 3 个数字,应由其 ID 替换。
示例:
SIM_WARNING[ANA397]: Node q<159> for vector output signal does not exist
输出应为 ANA397,其余行已删除。
如何使用 sed 做到这一点?
首先,您必须选择如何使用ID,例如您需要先循环文件还是稍后循环...
(先循环档)
exec 3<file
while read -r line <&3; do
id="$(printf "%s" "${line}" | sed -e "s/.*\[\([[:alnum:]]\+\)\].*//")"
### Do something with id
done
exec 3>&-
否则你可以决定循环sed的输出...
例如
for id in $(sed -e "s/.*\[\([[:alnum:]]\+\)\].*//" file); do
### Do something with id
done
这两个示例都应该与 posix shell 一起使用(如果我没有遗漏某些东西......),但是 shell 像 posh
可能不支持 类 与 [[:alnum:]]
相同,您可以将它们替换为等效的 [a-zA-Z0-9]
,每个 guide 都会教您。
请注意,检查不是检查 3 个字母和 3 个数字,而是检查括号内的任何字母和数字([
和 ]
)。
编辑:
如果您的行以 SIM_WARNING
开头,您可以用 -e "/^SIM_WARNING/! d"
区分这些行
要严格检查 3 个字母和 3 个数字,您可以使用 -e "s/.*\[\([a-zA-Z][a-zA-Z][a-zA-Z][0-9][0-9][0-9]\)\].*//"
以上面的例子为例,你可以这样做:
for id in $(sed -e "/^SIM_WARNING/! d" -e "s/.*\[\([a-zA-Z][a-zA-Z][a-zA-Z][0-9][0-9][0-9]\)\].*//" file)
### Do something with id
done
我认为您不需要为此使用 sed。带有 --only-matching
的简单 grep 可以做到,如:
grep -E 'SIM_WARNING\[(.)\]' --only-matching
应该适合你。
其中:
- -E 执行“增强的正则表达式。我 认为 我们需要那些用于捕获 ( )
- 然后遵循模式,它由固定的 SIM_WARNING 组成,后跟方括号
内的 匹配
- --only-matching 只是让grep打印only matching内容
换句话说:通过使用 ( match ) 你告诉 grep 你只关心那个匹配模式中的东西。
for id in $(grep -o "^SIM_WARNING\[[A-Z][A-Z][A-Z][0-9][0-9][0-9]\]" test1.bla | grep -o "[A-Z][A-Z][A-Z][0-9][0-9][0-9]" test1.bla ); do echo $id; done
这从下面找到 ANA397
。
SIM_WARNING[ANA397]: Node q<159> for vector output signal does not exist
假设我有一个带有警告的文件。新行中的每个警告的 ID 仅包含 3 个大写字母后跟 3 个数字,应由其 ID 替换。
示例:
SIM_WARNING[ANA397]: Node q<159> for vector output signal does not exist
输出应为 ANA397,其余行已删除。
如何使用 sed 做到这一点?
首先,您必须选择如何使用ID,例如您需要先循环文件还是稍后循环...
(先循环档)
exec 3<file
while read -r line <&3; do
id="$(printf "%s" "${line}" | sed -e "s/.*\[\([[:alnum:]]\+\)\].*//")"
### Do something with id
done
exec 3>&-
否则你可以决定循环sed的输出...
例如
for id in $(sed -e "s/.*\[\([[:alnum:]]\+\)\].*//" file); do
### Do something with id
done
这两个示例都应该与 posix shell 一起使用(如果我没有遗漏某些东西......),但是 shell 像 posh
可能不支持 类 与 [[:alnum:]]
相同,您可以将它们替换为等效的 [a-zA-Z0-9]
,每个 guide 都会教您。
请注意,检查不是检查 3 个字母和 3 个数字,而是检查括号内的任何字母和数字([
和 ]
)。
编辑:
如果您的行以 SIM_WARNING
开头,您可以用 -e "/^SIM_WARNING/! d"
要严格检查 3 个字母和 3 个数字,您可以使用 -e "s/.*\[\([a-zA-Z][a-zA-Z][a-zA-Z][0-9][0-9][0-9]\)\].*//"
以上面的例子为例,你可以这样做:
for id in $(sed -e "/^SIM_WARNING/! d" -e "s/.*\[\([a-zA-Z][a-zA-Z][a-zA-Z][0-9][0-9][0-9]\)\].*//" file)
### Do something with id
done
我认为您不需要为此使用 sed。带有 --only-matching
的简单 grep 可以做到,如:
grep -E 'SIM_WARNING\[(.)\]' --only-matching
应该适合你。
其中:
- -E 执行“增强的正则表达式。我 认为 我们需要那些用于捕获 ( )
- 然后遵循模式,它由固定的 SIM_WARNING 组成,后跟方括号 内的 匹配
- --only-matching 只是让grep打印only matching内容
换句话说:通过使用 ( match ) 你告诉 grep 你只关心那个匹配模式中的东西。
for id in $(grep -o "^SIM_WARNING\[[A-Z][A-Z][A-Z][0-9][0-9][0-9]\]" test1.bla | grep -o "[A-Z][A-Z][A-Z][0-9][0-9][0-9]" test1.bla ); do echo $id; done
这从下面找到 ANA397
。
SIM_WARNING[ANA397]: Node q<159> for vector output signal does not exist