Colon character is messing up my pattern match in Bash
I have a variable $line
, which can contain any of the following strings:
line="READ CACHE IS: ENABLED"
line="BLOCKS READ CACHE AND SENT TO INITIATOR = 2489338280"
line="ECC REREADS/ ERRORS ALGORITHM PROCESSED UNCORRECTED"
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
line="0x22 GPL R/O 1 READ STREAM ERROR LOG"
line="READ: DISABLED"
I have a script that compares the $line
variable against some patterns:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
Herein lies the problem. The colon is screwing everything up. I've tried every possible way of formatting the pattern to satisfy both possibilities of line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
or line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
When I escape the : as shown above. I can satisfy line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
but not line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
. If I take away the escape, then I satisfy line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
not line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
Sample Run 1:
line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 1:
0
Sample Run 2:
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 2:
<null>
Sample Run 3:
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 3:
0
How do I get the best of both worlds?
bash wildcards
|
show 1 more comment
I have a variable $line
, which can contain any of the following strings:
line="READ CACHE IS: ENABLED"
line="BLOCKS READ CACHE AND SENT TO INITIATOR = 2489338280"
line="ECC REREADS/ ERRORS ALGORITHM PROCESSED UNCORRECTED"
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
line="0x22 GPL R/O 1 READ STREAM ERROR LOG"
line="READ: DISABLED"
I have a script that compares the $line
variable against some patterns:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
Herein lies the problem. The colon is screwing everything up. I've tried every possible way of formatting the pattern to satisfy both possibilities of line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
or line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
When I escape the : as shown above. I can satisfy line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
but not line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
. If I take away the escape, then I satisfy line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
not line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
Sample Run 1:
line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 1:
0
Sample Run 2:
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 2:
<null>
Sample Run 3:
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 3:
0
How do I get the best of both worlds?
bash wildcards
These are all separate expressions; I don't see how changing one causes a different one to break. Can you edit in separate examples of each case that isn't working?
– Michael Homer
Sep 19 '18 at 2:59
1
@AfroJoe : I don't see the usage of regular expressions in your post. Note that regular expressions in bash are tested using the=~
operator, not==
(which matches against file expansion),
– user1934428
Sep 19 '18 at 6:35
@MichaelHomer EDITED: with sample runs. (copy/paste and try yourself) :)
– AfroJoe
Sep 19 '18 at 13:06
What's the problem with the third one? It matches the patternREAD:*
, and prints the eighth field, which is0
.
– ilkkachu
Sep 19 '18 at 13:18
The problem is the program loops through all the possible values of$line
(indicated above) and writes$devReadErr
as<null>
upon encounteringREAD: 2513550726 22 0 2513550748 2513550748 27768.965 0
when the colon is escaped.
– AfroJoe
Sep 19 '18 at 13:47
|
show 1 more comment
I have a variable $line
, which can contain any of the following strings:
line="READ CACHE IS: ENABLED"
line="BLOCKS READ CACHE AND SENT TO INITIATOR = 2489338280"
line="ECC REREADS/ ERRORS ALGORITHM PROCESSED UNCORRECTED"
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
line="0x22 GPL R/O 1 READ STREAM ERROR LOG"
line="READ: DISABLED"
I have a script that compares the $line
variable against some patterns:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
Herein lies the problem. The colon is screwing everything up. I've tried every possible way of formatting the pattern to satisfy both possibilities of line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
or line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
When I escape the : as shown above. I can satisfy line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
but not line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
. If I take away the escape, then I satisfy line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
not line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
Sample Run 1:
line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 1:
0
Sample Run 2:
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 2:
<null>
Sample Run 3:
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 3:
0
How do I get the best of both worlds?
bash wildcards
I have a variable $line
, which can contain any of the following strings:
line="READ CACHE IS: ENABLED"
line="BLOCKS READ CACHE AND SENT TO INITIATOR = 2489338280"
line="ECC REREADS/ ERRORS ALGORITHM PROCESSED UNCORRECTED"
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
line="0x22 GPL R/O 1 READ STREAM ERROR LOG"
line="READ: DISABLED"
I have a script that compares the $line
variable against some patterns:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
Herein lies the problem. The colon is screwing everything up. I've tried every possible way of formatting the pattern to satisfy both possibilities of line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
or line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
When I escape the : as shown above. I can satisfy line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
but not line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
. If I take away the escape, then I satisfy line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
not line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
Sample Run 1:
line="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 1:
0
Sample Run 2:
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 2:
<null>
Sample Run 3:
line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
fi
echo $devReadErr
Output of Run 3:
0
How do I get the best of both worlds?
bash wildcards
bash wildcards
edited 15 mins ago
Rui F Ribeiro
39.2k1479130
39.2k1479130
asked Sep 19 '18 at 2:18
AfroJoe
42518
42518
These are all separate expressions; I don't see how changing one causes a different one to break. Can you edit in separate examples of each case that isn't working?
– Michael Homer
Sep 19 '18 at 2:59
1
@AfroJoe : I don't see the usage of regular expressions in your post. Note that regular expressions in bash are tested using the=~
operator, not==
(which matches against file expansion),
– user1934428
Sep 19 '18 at 6:35
@MichaelHomer EDITED: with sample runs. (copy/paste and try yourself) :)
– AfroJoe
Sep 19 '18 at 13:06
What's the problem with the third one? It matches the patternREAD:*
, and prints the eighth field, which is0
.
– ilkkachu
Sep 19 '18 at 13:18
The problem is the program loops through all the possible values of$line
(indicated above) and writes$devReadErr
as<null>
upon encounteringREAD: 2513550726 22 0 2513550748 2513550748 27768.965 0
when the colon is escaped.
– AfroJoe
Sep 19 '18 at 13:47
|
show 1 more comment
These are all separate expressions; I don't see how changing one causes a different one to break. Can you edit in separate examples of each case that isn't working?
– Michael Homer
Sep 19 '18 at 2:59
1
@AfroJoe : I don't see the usage of regular expressions in your post. Note that regular expressions in bash are tested using the=~
operator, not==
(which matches against file expansion),
– user1934428
Sep 19 '18 at 6:35
@MichaelHomer EDITED: with sample runs. (copy/paste and try yourself) :)
– AfroJoe
Sep 19 '18 at 13:06
What's the problem with the third one? It matches the patternREAD:*
, and prints the eighth field, which is0
.
– ilkkachu
Sep 19 '18 at 13:18
The problem is the program loops through all the possible values of$line
(indicated above) and writes$devReadErr
as<null>
upon encounteringREAD: 2513550726 22 0 2513550748 2513550748 27768.965 0
when the colon is escaped.
– AfroJoe
Sep 19 '18 at 13:47
These are all separate expressions; I don't see how changing one causes a different one to break. Can you edit in separate examples of each case that isn't working?
– Michael Homer
Sep 19 '18 at 2:59
These are all separate expressions; I don't see how changing one causes a different one to break. Can you edit in separate examples of each case that isn't working?
– Michael Homer
Sep 19 '18 at 2:59
1
1
@AfroJoe : I don't see the usage of regular expressions in your post. Note that regular expressions in bash are tested using the
=~
operator, not ==
(which matches against file expansion),– user1934428
Sep 19 '18 at 6:35
@AfroJoe : I don't see the usage of regular expressions in your post. Note that regular expressions in bash are tested using the
=~
operator, not ==
(which matches against file expansion),– user1934428
Sep 19 '18 at 6:35
@MichaelHomer EDITED: with sample runs. (copy/paste and try yourself) :)
– AfroJoe
Sep 19 '18 at 13:06
@MichaelHomer EDITED: with sample runs. (copy/paste and try yourself) :)
– AfroJoe
Sep 19 '18 at 13:06
What's the problem with the third one? It matches the pattern
READ:*
, and prints the eighth field, which is 0
.– ilkkachu
Sep 19 '18 at 13:18
What's the problem with the third one? It matches the pattern
READ:*
, and prints the eighth field, which is 0
.– ilkkachu
Sep 19 '18 at 13:18
The problem is the program loops through all the possible values of
$line
(indicated above) and writes $devReadErr
as <null>
upon encountering READ: 2513550726 22 0 2513550748 2513550748 27768.965 0
when the colon is escaped.– AfroJoe
Sep 19 '18 at 13:47
The problem is the program loops through all the possible values of
$line
(indicated above) and writes $devReadErr
as <null>
upon encountering READ: 2513550726 22 0 2513550748 2513550748 27768.965 0
when the colon is escaped.– AfroJoe
Sep 19 '18 at 13:47
|
show 1 more comment
2 Answers
2
active
oldest
votes
You should remove the in front of
:
in that second test, or it will try to match against a literal character.
These are not regular expression matches you are doing, but shell globbing pattern matches (just as on the command line when you are using *
in patterns). This doesn't really matter in this case.
I'm assuming that you'd like to extract the 20 from the two first strings and store it in devReadErr
, but not when the line reads READ: DISABLED
. This is exactly what your code does if the is removed:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $2}')
fi
Another way to do the same thing:
if [[ "$line" != *'DISABLED' ]]; then
devReadErr=${line##* }
fi
This extracts the number as the string after the last space character in $line
if the string does not end with the word DISABLED
. This avoids the echo
and awk
.
If this is part of a larger loop that parses a file line by line, then I would suggest writing it in awk
or some other language designed to parse text. See, e.g., Why is using a shell loop to process text considered bad practice?.
I edited the question with way more detail and sample runs. As you indicated Kusalananda, its apart of a larger loop. The use of awk is definitely an option, but I'd like to see if the collective can figure out the underlying behaviour of how BASH is working towards processing the expression.
– AfroJoe
Sep 19 '18 at 13:09
add a comment |
I suspect you want:
if [[ $line = *RAW_READ_ERROR_RATE* ||
$line = READ:* && $line != *"READ: DISABLED"* ]]; then
The &&
[[...]]
operator has precedence over ||
but the &&
shell operator has same precedence as ||
.
Or to make it explicit:
if [[ $line = *RAW_READ_ERROR_RATE* ||
($line = READ:* && $line != *"READ: DISABLED"*) ]]; then
Or using the &&
/||
shell operators and multiple [[...]]
s:
if [[ $line = *RAW_READ_ERROR_RATE* ]] || {
[[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]]; }; then
Or change the order:
if [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]] ||
[[ $line = *RAW_READ_ERROR_RATE* ]]; then
Or use a pattern that matches all:
if [[ $line = @(*RAW_READ_ERROR_RATE*|!(!(*READ:*)|*READ: DISABLED*)) ]]; then
Without the parenthesis/braces, yours is read as:
if [[ ($line = *RAW_READ_ERROR_RATE* ||
$line = READ:*) && $line != *"READ: DISABLED"* ]]; then
That shouldn't prevent it from matching lines that contain RAW_READ_ERROR_RATE
though provided they don't contain READ: DISABLED
.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f469914%2fcolon-character-is-messing-up-my-pattern-match-in-bash%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
You should remove the in front of
:
in that second test, or it will try to match against a literal character.
These are not regular expression matches you are doing, but shell globbing pattern matches (just as on the command line when you are using *
in patterns). This doesn't really matter in this case.
I'm assuming that you'd like to extract the 20 from the two first strings and store it in devReadErr
, but not when the line reads READ: DISABLED
. This is exactly what your code does if the is removed:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $2}')
fi
Another way to do the same thing:
if [[ "$line" != *'DISABLED' ]]; then
devReadErr=${line##* }
fi
This extracts the number as the string after the last space character in $line
if the string does not end with the word DISABLED
. This avoids the echo
and awk
.
If this is part of a larger loop that parses a file line by line, then I would suggest writing it in awk
or some other language designed to parse text. See, e.g., Why is using a shell loop to process text considered bad practice?.
I edited the question with way more detail and sample runs. As you indicated Kusalananda, its apart of a larger loop. The use of awk is definitely an option, but I'd like to see if the collective can figure out the underlying behaviour of how BASH is working towards processing the expression.
– AfroJoe
Sep 19 '18 at 13:09
add a comment |
You should remove the in front of
:
in that second test, or it will try to match against a literal character.
These are not regular expression matches you are doing, but shell globbing pattern matches (just as on the command line when you are using *
in patterns). This doesn't really matter in this case.
I'm assuming that you'd like to extract the 20 from the two first strings and store it in devReadErr
, but not when the line reads READ: DISABLED
. This is exactly what your code does if the is removed:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $2}')
fi
Another way to do the same thing:
if [[ "$line" != *'DISABLED' ]]; then
devReadErr=${line##* }
fi
This extracts the number as the string after the last space character in $line
if the string does not end with the word DISABLED
. This avoids the echo
and awk
.
If this is part of a larger loop that parses a file line by line, then I would suggest writing it in awk
or some other language designed to parse text. See, e.g., Why is using a shell loop to process text considered bad practice?.
I edited the question with way more detail and sample runs. As you indicated Kusalananda, its apart of a larger loop. The use of awk is definitely an option, but I'd like to see if the collective can figure out the underlying behaviour of how BASH is working towards processing the expression.
– AfroJoe
Sep 19 '18 at 13:09
add a comment |
You should remove the in front of
:
in that second test, or it will try to match against a literal character.
These are not regular expression matches you are doing, but shell globbing pattern matches (just as on the command line when you are using *
in patterns). This doesn't really matter in this case.
I'm assuming that you'd like to extract the 20 from the two first strings and store it in devReadErr
, but not when the line reads READ: DISABLED
. This is exactly what your code does if the is removed:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $2}')
fi
Another way to do the same thing:
if [[ "$line" != *'DISABLED' ]]; then
devReadErr=${line##* }
fi
This extracts the number as the string after the last space character in $line
if the string does not end with the word DISABLED
. This avoids the echo
and awk
.
If this is part of a larger loop that parses a file line by line, then I would suggest writing it in awk
or some other language designed to parse text. See, e.g., Why is using a shell loop to process text considered bad practice?.
You should remove the in front of
:
in that second test, or it will try to match against a literal character.
These are not regular expression matches you are doing, but shell globbing pattern matches (just as on the command line when you are using *
in patterns). This doesn't really matter in this case.
I'm assuming that you'd like to extract the 20 from the two first strings and store it in devReadErr
, but not when the line reads READ: DISABLED
. This is exactly what your code does if the is removed:
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $2}')
fi
Another way to do the same thing:
if [[ "$line" != *'DISABLED' ]]; then
devReadErr=${line##* }
fi
This extracts the number as the string after the last space character in $line
if the string does not end with the word DISABLED
. This avoids the echo
and awk
.
If this is part of a larger loop that parses a file line by line, then I would suggest writing it in awk
or some other language designed to parse text. See, e.g., Why is using a shell loop to process text considered bad practice?.
answered Sep 19 '18 at 5:51
Kusalananda
122k16230375
122k16230375
I edited the question with way more detail and sample runs. As you indicated Kusalananda, its apart of a larger loop. The use of awk is definitely an option, but I'd like to see if the collective can figure out the underlying behaviour of how BASH is working towards processing the expression.
– AfroJoe
Sep 19 '18 at 13:09
add a comment |
I edited the question with way more detail and sample runs. As you indicated Kusalananda, its apart of a larger loop. The use of awk is definitely an option, but I'd like to see if the collective can figure out the underlying behaviour of how BASH is working towards processing the expression.
– AfroJoe
Sep 19 '18 at 13:09
I edited the question with way more detail and sample runs. As you indicated Kusalananda, its apart of a larger loop. The use of awk is definitely an option, but I'd like to see if the collective can figure out the underlying behaviour of how BASH is working towards processing the expression.
– AfroJoe
Sep 19 '18 at 13:09
I edited the question with way more detail and sample runs. As you indicated Kusalananda, its apart of a larger loop. The use of awk is definitely an option, but I'd like to see if the collective can figure out the underlying behaviour of how BASH is working towards processing the expression.
– AfroJoe
Sep 19 '18 at 13:09
add a comment |
I suspect you want:
if [[ $line = *RAW_READ_ERROR_RATE* ||
$line = READ:* && $line != *"READ: DISABLED"* ]]; then
The &&
[[...]]
operator has precedence over ||
but the &&
shell operator has same precedence as ||
.
Or to make it explicit:
if [[ $line = *RAW_READ_ERROR_RATE* ||
($line = READ:* && $line != *"READ: DISABLED"*) ]]; then
Or using the &&
/||
shell operators and multiple [[...]]
s:
if [[ $line = *RAW_READ_ERROR_RATE* ]] || {
[[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]]; }; then
Or change the order:
if [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]] ||
[[ $line = *RAW_READ_ERROR_RATE* ]]; then
Or use a pattern that matches all:
if [[ $line = @(*RAW_READ_ERROR_RATE*|!(!(*READ:*)|*READ: DISABLED*)) ]]; then
Without the parenthesis/braces, yours is read as:
if [[ ($line = *RAW_READ_ERROR_RATE* ||
$line = READ:*) && $line != *"READ: DISABLED"* ]]; then
That shouldn't prevent it from matching lines that contain RAW_READ_ERROR_RATE
though provided they don't contain READ: DISABLED
.
add a comment |
I suspect you want:
if [[ $line = *RAW_READ_ERROR_RATE* ||
$line = READ:* && $line != *"READ: DISABLED"* ]]; then
The &&
[[...]]
operator has precedence over ||
but the &&
shell operator has same precedence as ||
.
Or to make it explicit:
if [[ $line = *RAW_READ_ERROR_RATE* ||
($line = READ:* && $line != *"READ: DISABLED"*) ]]; then
Or using the &&
/||
shell operators and multiple [[...]]
s:
if [[ $line = *RAW_READ_ERROR_RATE* ]] || {
[[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]]; }; then
Or change the order:
if [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]] ||
[[ $line = *RAW_READ_ERROR_RATE* ]]; then
Or use a pattern that matches all:
if [[ $line = @(*RAW_READ_ERROR_RATE*|!(!(*READ:*)|*READ: DISABLED*)) ]]; then
Without the parenthesis/braces, yours is read as:
if [[ ($line = *RAW_READ_ERROR_RATE* ||
$line = READ:*) && $line != *"READ: DISABLED"* ]]; then
That shouldn't prevent it from matching lines that contain RAW_READ_ERROR_RATE
though provided they don't contain READ: DISABLED
.
add a comment |
I suspect you want:
if [[ $line = *RAW_READ_ERROR_RATE* ||
$line = READ:* && $line != *"READ: DISABLED"* ]]; then
The &&
[[...]]
operator has precedence over ||
but the &&
shell operator has same precedence as ||
.
Or to make it explicit:
if [[ $line = *RAW_READ_ERROR_RATE* ||
($line = READ:* && $line != *"READ: DISABLED"*) ]]; then
Or using the &&
/||
shell operators and multiple [[...]]
s:
if [[ $line = *RAW_READ_ERROR_RATE* ]] || {
[[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]]; }; then
Or change the order:
if [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]] ||
[[ $line = *RAW_READ_ERROR_RATE* ]]; then
Or use a pattern that matches all:
if [[ $line = @(*RAW_READ_ERROR_RATE*|!(!(*READ:*)|*READ: DISABLED*)) ]]; then
Without the parenthesis/braces, yours is read as:
if [[ ($line = *RAW_READ_ERROR_RATE* ||
$line = READ:*) && $line != *"READ: DISABLED"* ]]; then
That shouldn't prevent it from matching lines that contain RAW_READ_ERROR_RATE
though provided they don't contain READ: DISABLED
.
I suspect you want:
if [[ $line = *RAW_READ_ERROR_RATE* ||
$line = READ:* && $line != *"READ: DISABLED"* ]]; then
The &&
[[...]]
operator has precedence over ||
but the &&
shell operator has same precedence as ||
.
Or to make it explicit:
if [[ $line = *RAW_READ_ERROR_RATE* ||
($line = READ:* && $line != *"READ: DISABLED"*) ]]; then
Or using the &&
/||
shell operators and multiple [[...]]
s:
if [[ $line = *RAW_READ_ERROR_RATE* ]] || {
[[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]]; }; then
Or change the order:
if [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]] ||
[[ $line = *RAW_READ_ERROR_RATE* ]]; then
Or use a pattern that matches all:
if [[ $line = @(*RAW_READ_ERROR_RATE*|!(!(*READ:*)|*READ: DISABLED*)) ]]; then
Without the parenthesis/braces, yours is read as:
if [[ ($line = *RAW_READ_ERROR_RATE* ||
$line = READ:*) && $line != *"READ: DISABLED"* ]]; then
That shouldn't prevent it from matching lines that contain RAW_READ_ERROR_RATE
though provided they don't contain READ: DISABLED
.
edited Sep 19 '18 at 14:58
answered Sep 19 '18 at 13:15
Stéphane Chazelas
300k54564913
300k54564913
add a comment |
add a comment |
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f469914%2fcolon-character-is-messing-up-my-pattern-match-in-bash%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
These are all separate expressions; I don't see how changing one causes a different one to break. Can you edit in separate examples of each case that isn't working?
– Michael Homer
Sep 19 '18 at 2:59
1
@AfroJoe : I don't see the usage of regular expressions in your post. Note that regular expressions in bash are tested using the
=~
operator, not==
(which matches against file expansion),– user1934428
Sep 19 '18 at 6:35
@MichaelHomer EDITED: with sample runs. (copy/paste and try yourself) :)
– AfroJoe
Sep 19 '18 at 13:06
What's the problem with the third one? It matches the pattern
READ:*
, and prints the eighth field, which is0
.– ilkkachu
Sep 19 '18 at 13:18
The problem is the program loops through all the possible values of
$line
(indicated above) and writes$devReadErr
as<null>
upon encounteringREAD: 2513550726 22 0 2513550748 2513550748 27768.965 0
when the colon is escaped.– AfroJoe
Sep 19 '18 at 13:47