Quantcast
Channel: User Kamil Maciorowski - Super User
Viewing all articles
Browse latest Browse all 656

Answer by Kamil Maciorowski for if then statement only acting on first instance of matching string

$
0
0

Initially the WARN variable contains multiple lines. Still, like any non-array shell variable it's just a single string and the fact there are newline characters inside does not change this.

[[ "$WARN" == *Failed* ]] tests if there is a substring Failedanywhere inside the string. It's one test acting on the entire string, not "per line".

Similarly the substitution in ${WARN//\'*\'./...} (for brevity I removed the unnecessary backslash and two pairs of single-quotes that embraced an empty string each) acts on the entire string at once, not "per line"; and because * is greedy then there is a match that starts inside the first "failed" line and ends at the last "failed" line. In other words the match includes several single-quotes and several newline characters, all this is replaced by ....

In yet other words: the line with ... you saw in the output consists of the beginning of some line, the ... and the end of a different line.

Use a tool that processes one line at a time, e.g. sed:

<<<"$WARN" sed "/Failed/ s/'.*'\\./.../"

Note .* in '.*' is greedy, it can match a string containing ' (or even a newline character); but now there is no problem because our sed processes each line separately.

You can filter out "similar" lines by piping to uniq:

<<<"$WARN" sed "/Failed/ s/'.*'\\./.../" | uniq -f 3

uniq -f 3 ignores the first three fields, which are (W), the timestamp and - in your case. This way different timestamps do not prevent lines from being considered equal, only the content that follows matters. It seems this is what you want.

More complex logic can be implemented e.g. with awk.

Maybe you can do it without the variable. If the value of the variable came from the output of some_tool then this may be enough:

some_tool | sed "/Failed/ s/'.*'\\./.../" | uniq -f 3

If the value of the variable came from a_file then this may be enough:

<a_file sed "/Failed/ s/'.*'\\./.../" | uniq -f 3

Viewing all articles
Browse latest Browse all 656

Trending Articles