$line
次の文字列のいずれかを含めることができる変数があります。
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"
$line
変数をいくつかのパターンと比較するスクリプトがあります。
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ\:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $8}')
それが問題だ。コロンはすべてを台無しにします。上記のように:をエスケープするときに、両方の可能性をline="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
満たすようにパターンをフォーマットするすべての可能な方法を試しました。line="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
満足できline="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
ましたがline="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
…脱出を奪うとline="READ: 2513550726 22 0 2513550748 2513550748 27768.965 0"
満足できないline="1 RAW_READ_ERROR_RATE PO-R-- 100 100 016 - 0"
実行例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
実行1の出力:
0
実行例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
実行2の出力:
<null>
実行例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
実行3の出力:
0
どうすれば両方の世界の利点を得ることができますか?
答え1
2番目のテストでは、\
前の項目を削除する必要があります。それ以外の場合は、リテラル文字:
と一致しようとします。\
これは、実行中の正規表現の一致ではなく、シェルワイルドカードパターンの一致です(*
コマンドラインでパターンに使用する場合と同じです)。この場合は問題ではありません。
最初の2つの文字列から20を抽出して保存しようとしていますdevReadErr
が、行を読み取るときはそうでないとしますREAD: DISABLED
。削除された場合、\
コードが実行する操作は次のとおりです。
if [[ ${line} == *"RAW_READ_ERROR_RATE"* ]] ||
[[ ${line} == "READ:"* ]] &&
[[ ${line} != *"READ: DISABLED"* ]]; then
devReadErr=$(echo "$line" | awk '{print $2}')
fi
同じタスクを実行する別の方法:
if [[ "$line" != *'DISABLED' ]]; then
devReadErr=${line##* }
fi
$line
文字列が単語で終わらない場合、数字は最後の空白文字の後の文字列として抽出されますDISABLED
。これはとecho
を防ぎますawk
。
awk
これがファイルを1行ずつ解析するより大きなループの一部である場合は、テキストを解析するように設計された別の言語で書くことをお勧めします。たとえば、次を参照してください。 シェルループを使用してテキストを処理するのはなぜ悪い習慣と見なされますか?。
答え2
私はあなたが欲しいと思います:
if [[ $line = *RAW_READ_ERROR_RATE* ||
$line = READ:* && $line != *"READ: DISABLED"* ]]; then
演算子が&&
[[...]]
優先され||
ますが&&
シェル演算子はと同じ優先順位を持ちます||
。
または明示的に:
if [[ $line = *RAW_READ_ERROR_RATE* ||
($line = READ:* && $line != *"READ: DISABLED"*) ]]; then
または、複数のsで&&
/シェル演算子を使用してください。||
[[...]]
if [[ $line = *RAW_READ_ERROR_RATE* ]] || {
[[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]]; }; then
または順序を変更してください。
if [[ $line = READ:* ]] && [[ $line != *"READ: DISABLED"* ]] ||
[[ $line = *RAW_READ_ERROR_RATE* ]]; then
または、すべてに一致するパターンを使用します。
if [[ $line = @(*RAW_READ_ERROR_RATE*|!(!(*READ:*)|*READ:\ DISABLED*)) ]]; then
括弧/中括弧がない場合、コンテンツは次のように解釈されます。
if [[ ($line = *RAW_READ_ERROR_RATE* ||
$line = READ:*) && $line != *"READ: DISABLED"* ]]; then
これは、whileRAW_READ_ERROR_RATE
が含まれていない場合に含まれる行と一致することを妨げてはいけませんREAD: DISABLED
。