bashスクリプトのifステートメント内に改行文字を含むgrep出力を表示する

bashスクリプトのifステートメント内に改行文字を含むgrep出力を表示する

スクリプトを使用してテキストファイルを検証したいと思います。

確認するファイルは次のとおりです。

FDFHDK JKL
1545665 152
HDKFHDK UHG
YRYRUBH DFG
867HDKE WER

有効な行は正規表現と一致する必要があります'[A-Z]{7}+[[:space:]]+[A-Z]{3}'

すべての行が有効な場合、スクリプトはファイルが正常であることを示すメッセージを表示します。

1つ以上の行が正規表現と一致しない場合、スクリプトはメッセージを表示し、正規表現と一致しない行を表示する必要があります。

スクリプトは次のとおりです。

#!/usr/bin/env bash
result=""
output=$(grep -vE '[A-Z]{7}+[[:space:]]+[A-Z]{3}' "$1" |wc -l)
if [[ $output > 0 ]]
then
  echo "These lines don't match:"
  result="${resultado} $(grep -vE '[A-Z]{7}+[[:space:]]+[A-Z]{3}' "$1") \n"
  echo -e $result
else
  echo "The text file is valid"
fi  

予想される出力は次のとおりです。

These lines don't match
FDFHDK JKL
1545665 152
867HDKE WER

しかし、ますます多くなります。

These lines don't match:
FDFHDK JKL 1545665 152 867HDKE WER

したがって、実際のスクリプトでは改行文字を考慮しません。

答え1

テストを実行したり、そのデータを出力するためにコマンドの出力を保存するために中間変数を使用する理由はまったくありません。

#!/bin/sh -

if grep -q -v -x -E -e '[A-Z]{7}[[:space:]]+[A-Z]{3}' -- "$1"
then
    echo 'Does not verify. Bad lines follow...'
    grep -v -x -E -e '[A-Z]{7}[[:space:]]+[A-Z]{3}' -- "$1"
fi

+重複した内容を削除するために正規表現が修正されました{7}。このifステートメントは終了ステータスを直接テストしますgrep。ステートメントgrep内のコマンドifとその後のコマンド-xは、行全体の一致を強制するために使用され、最初のステートメントは何も出力せずに最初の一致で停止するgrepために使用されます。-q

コードの実際の問題は、$result引用符なしで使用することです。これにより、シェルは値をスペース、タブ、および改行に分割し、結果の単語に対してファイル名のグロービングを実行します。次に、最後の単語セットを引数として提供し、echoスペースを区切り文字として印刷します。


2回実行するのが心配な場合は、grep一度だけ実行して出力を一時ファイルに保存してください。

#!/bin/sh -

tmpfile=$(mktemp)

if grep -v -x -E -e '[A-Z]{7}[[:space:]]+[A-Z]{3}' -- "$1" >"$tmpfile"
then
    echo 'Does not verify. Bad lines follow...'
    cat -- "$tmpfile"
fi

rm -f -- "$tmpfile"

答え2

私はこの選択肢を提案します:

match="$(grep -vEx '[A-Z]{7}[[:space:]]+[A-Z]{3}' "$1")"
[[ "${#match}" -ne 0 ]] && printf "%b\n" "Bad lines:\n${match[@]}"
Bad lines:
FDFHDK JKL
1545665 152
867HDKE WER


ノート@themの答え:

正規表現が修正され、その後の重複した+内容が削除されました。{7}

関連情報