grep経由で確認できない

grep経由で確認できない
list="feature test release"
branch=feature/fix

ブランチ名がリストのプレフィックスで始まっていないことを確認してから、コマンドを終了しようとします。ブランチにリストのプレフィックスの1つがある場合は有効です。

 echo $list| grep -e "$branch/[a-zA-Z0-9]" ; echo $?

残念ながら、このコマンドは機能しません。どんなアイデアがありますか?つまりtest/bla、有効な分岐名ですがtesttest/blaそうではありません。

編集:を使用していますsh。有効なプレフィックスのリストは単一の文字列または配列であり、両方を使用できます。

答え1

変数に有効なプレフィックスが必要ない場合は、次のいずれかの回避策を使用できます。

たとえば、feature/foo/bar有効かどうかに応じて、最後の1つだけを削除するか、/*すべて削除する必要があります。

branchaが含まれていることを確認するには、別々のテストが必要な場合があります/

check.sh:

#!/bin/sh

# foo/bar --> ^foo$
# foo --> ^foo$
# foo/bar/baz --> ^foo$
pattern='^'"${branch%%/*}"'$'

# search for pattern in input, suppress output
grep "$pattern" >/dev/null <<EOF
feature
test
release
EOF

echo $?

テスト

$ branch=featur/fix ./check.sh
0
$ branch=foo/fix ./check.sh
1
$ branch=xfeature/fix ./check.sh
1
$ branch=featurex/fix ./check.sh
1

編集する:

で述べたようにスティーブン・チャジェラスbranch='.*''指定されたブランチ名にforなどの正規表現メタ文字が含まれている場合、上記の回避策は予期しない一致を生成する可能性があります。

確認したい正確な値に応じて、文字列をなどの区切り文字で囲むことでこれを防ぐことができます/

# ...
pattern="/${branch%%/*}/"
# ...
fgrep "$pattern" >/dev/null <<EOF
/feature/
/test/
/release/
EOF
# ...

check2.sh:

#!/bin/sh

# removes longest match /*
# foo/bar/baz --> foo
case "${branch%%/*}" in
feature|test|release)
    echo valid 1
    ;;
*)
    echo invalid 1
    ;;
esac

# removes shortedt match /*
# foo/bar/baz --> foo/bar
case "${branch%/*}" in
feature|test|release)
    echo valid 2
    ;;
*)
    echo invalid 2
    ;;
esac

テスト

$ branch=feature/fix ./check2.sh
valid 1
valid 2
$ branch=feature/fix/bla ./check2.sh
valid 1
invalid 2
$ branch=xfeature/fix ./check2.sh
invalid 1
invalid 2
$ branch=featurex/fix ./check2.sh
invalid 1
invalid 2

答え2

スカラー変数にスペースで区切られた単語のリストが含まれていて、その単語の後に1つ以上のASCII算術が$list続くことを確認したい場合は、POSIXでは次のことができます。$branch/sh

validate() (export LC_ALL=C
  list=$1 branch=$2
  case $branch in
    (*' '*) return 1;;
  esac
  case ${branch##*/} in
    ("" | *[![:alnum:]]*) return 1;;
  esac
  case " $list " in
    (*" ${branch%/*} "*) return 0;;
    (*) return 1;;
  esac
)

それから:

if validate "$list" "$branch"; then
  echo OK
else
  echo KO
fi

行ではなくランダムな文字列に対して正規表現一致を実行するには、POSIXlyのデフォルトオプションはexprand it's:演算子です。デフォルトの正規表現を使用し、and it awk's~演算子(拡張正規表現を使用する)といくつかの設計上の問題があります。

ここでは、次のようにします($list正規表現演算子ではない単語があるとします)。

validate() {
  LC_ALL=C awk -- '
    BEGIN {
      regexp = ARGV[1]
      branch = ARGV[2]
      gsub(" ", "|", regexp)
      regexp = "^("regexp")/[a-zA-Z0-9]+$"
      exit !(branch ~ regexp)
    }' "$@"
}

(ここではPOSIX文字クラスをサポートしていない実装がまだ発生するため、[a-zA-Z0-9]代わりに使用されました。)[[:alnum:]]awk

覚えておくべきいくつかの点は次のとおりです。

  • grep行単位で動作するため、その文字列に改行文字が含まれていないことを確認しない限り、任意の文字列を検証するために使用することはできません。
  • echo $listPOSIXシェルでは、パラメータ拡張を引用する必要があります。それ以外の場合は分割+glob(no )の影響を受けます。
  • echo任意のデータを出力するのには使用できませんので、必ずご使用printfください。echo $listprintf '%s\n' "$list"
  • このような範囲は0-9A-Za-zC 言語環境でのみ使用できます。 Cロケールでは、[0-9A-Za-z]同じコンテンツと正確に一致します[[:alnum:]]

答え3

@Bodoの1行バージョンの評価は次のとおりです。

echo $list | tr ' ' '\n' | grep '^'"${branch%%/*}"'$'; if [[ $? -eq 0 ]]; then echo  "VALID NAME"; else echo "NOPE"; exit 1; fi;

答え4

これにより、

list="feature test release"
branch=feature/fix
echo $list| grep -e "$branch/[a-zA-Z0-9]"

$IFS(そして引用するのを忘れたので修正されなかったと仮定すると$list) 実際に次のように作成しています。

echo feature test release | grep -e 'feature/fix/[a-zA-Z0-9]'

feature/fix/Xこれは文字列内のすべての英数字のパターンを探します。それは動作しません。Xfeature test release

リスト形式を正規表現に変更し、タグを正規表現と比較できます。

listRE="^($(printf '%s\n' "$list" | tr ' ' '|'))/"    # ^(feature|test|release)/
printf '%s\n' "$branch" | grep -E "$listRE"; echo "$?"

関連情報