我在这里缺少一些知识,也没有合适的语言来描述(抱歉)。这是我的命令,它只在找到“$WARN”中的匹配项时返回第一个实例
echo "$WARN"
(W) 2024-08-30T08:08:52 - Restart is required to toggle support
(W) 2024-08-30T09:59:30 - Failed to download RSS feed at 'https://aaa'. Reason: The connection to the remote server timed out
(W) 2024-08-30T10:00:30 - Failed to download RSS feed at 'https://bbb'. Reason: The connection to the remote server timed out
(W) 2024-08-30T10:00:30 - Failed to download RSS feed at 'https://ccc'. Reason: The connection to the remote server timed out
(W) 2024-09-13T08:59:44 - Failed to download RSS feed at 'http://xxx'. Reason: The remote server refused the connection
(W) 2024-09-13T08:59:44 - Failed to download RSS feed at 'http://yyy'. Reason: The remote server refused the connection
(W) 2024-09-13T08:59:44 - Failed to download RSS feed at 'http://zzz'. Reason: The remote server refused the connection
WARN=$(
if [[ "$WARN" == *Failed* ]]
then
printf '%s' "${WARN//''\'*''\'\./...}"
fi
)
echo "$WARN"
(W) 2024-08-30T08:08:52 - Restart is required to toggle support
(W) 2024-08-30T09:59:30 - Failed to download RSS feed at ... Reason: The connection to the remote server timed out
预期输出:唯一行和与“失败”匹配的行被修改以删除单引号内的所有内容,包括引号本身。
(W) 2024-08-30T08:08:52 - Restart is required to toggle support
(W) 2024-08-30T09:59:30 - Failed to download RSS feed at ... Reason: The connection to the remote server timed out
(W) 2024-09-13T08:59:44 - Failed to download RSS feed at ... Reason: The remote server refused the connection
实际输出:为什么省略了第二行的考虑,即只有包含的第一个匹配的行Failed
被执行并返回。
echo "$WARN"
(W) 2024-08-30T08:08:52 - Restart is required to toggle support
(W) 2024-08-30T09:59:30 - Failed to download RSS feed at ... Reason: The connection to the remote server timed out
如果我对输入进行排序,则将其反转,第二次匹配的出现Failed
会被省略。
echo "$WARN"
(W) 2024-09-13T08:59:44 - Failed to download RSS feed at ... Reason: The remote server refused the connection
(W) 2024-08-30T08:08:52 - Restart is required to toggle support
我不想匹配字符串的末尾。
我第二次创建变量 $WARN 时,用新内容替换它。
最初,
WARN
变量包含多行。不过,与任何非数组 shell 变量一样,它只是一个字符串,而且里面有换行符这一事实不会改变这一点。[[ "$WARN" == *Failed* ]]
Failed
测试字符串中是否存在子字符串。这是针对整个字符串进行的一次测试,而不是“每行”测试。类似地,中的替换
${WARN//\'*\'./...}
(为简洁起见,我删除了不必要的反斜杠和两对包含空字符串的单引号)一次作用于整个字符串,而不是“每行”;并且由于是*
贪婪的,因此存在一个匹配,该匹配从第一个“失败”行开始,到最后一个“失败”行结束。换句话说,匹配包括几个单引号和几个换行符,所有这些都被替换为...
。换句话说:
...
您在输出中看到的行由某行的开头、和不同...
行的结尾组成。使用一次处理一行的工具,例如
sed
:注意
.*
是'.*'
贪婪的,它可以匹配包含'
(甚至是换行符)的字符串;但是现在没有问题,因为我们sed
分别处理每一行。您可以通过管道过滤掉“类似”的行
uniq
:uniq -f 3
忽略前三个字段,即(W)
、时间戳和-
(就您而言)。这样,不同的时间戳不会妨碍行被视为相等,只有后面的内容才重要。这似乎就是您想要的。可以实现更复杂的逻辑,例如使用
awk
。也许你可以不使用变量来做到这一点。如果变量的值来自输出,那么
some_tool
这可能就足够了:如果变量的值来自
a_file
那么这可能就足够了: