Shell-读取时跳过匹配行

时间:2019-04-04 09:57:04

标签: bash

我正在为我的外壳寻求帮助...希望我会在这里找到它...

这是我的代码:

#!/bin/sh
while IFS= read -r line || [ -n "$line" ]
do
  [[ "$line" =~ ^[[:space:]]*\# ]] && continue # This line must stay
  [[ "$line" =~ *read[[:space:]]-r[[:space:]]line* ]] && continue
  echo "${line%$NL}"
done < $0

第一次测试将取消“仅注释行”。 第二个测试目的是禁止显示“ while IFS = read ...”行-无论如何,这只是一个测试:-)

“完成<$ 0”在这里是故意写的...用于测试!

运行shell输出以下内容:

while IFS= read -r line || [ -n "$line" ]
do
    [[ "$line" =~ ^[[:space:]]*\# ]] && continue # This line must stay
    [[ "$line" =~ *read[[:space:]]-r[[:space:]]line* ]] && continue
    echo "${line%$NL}"
done < $0

我以为第一行会因为匹配第二个测试而消失。

我怎么了?

为了记录,我不想使用多余的sed或awk句子。

实际上,输入数据(此处为$ 0文件)必须是标准输入(例如,从tee命令中提取)。我阅读了很多关于stackOverflow的主题,它们的sed或awk响应与我的目的不符。

2 个答案:

答案 0 :(得分:1)

正则表达式无效。简短测试显示:

> [[ 'while IFS= read -r line || [ -n "$line" ]' =~ *read[[:space:]]-r[[:space:]]line* ]]
> echo $?
2

*不能是“单独的”-它不能是POSIX extended regular expression中的第一个字符。例如,它必须“绑定”到某物。点.。点代表任何字符。您想要:

[[ $line =~ .*read[[:space:]]-r[[:space:]]line.* ]]

答案 1 :(得分:1)

问题是第二行*的正则表达式中存在起始量词continue。您可以使用:

[[ "$line" =~ read[[:space:]]+-r[[:space:]]+line ]] && continue

在此正则表达式中,read之前或line之后无需匹配任何内容。

另外,最好在+之后使用量词[[:space:]]使其匹配1个或多个空格。


您可以执行更多的重构,并通过使用以下代码中的 alternation 将两个正则表达式合并为一个:

while IFS= read -r line || [[ -n $line ]]
do
  [[ $line =~ ^[[:space:]]*#|read[[:space:]]+-r[[:space:]]+line ]] && continue
  echo "${line%$NL}"
done < $0