個々の文字/数字の代わりに括弧を使用してパターンを一致させるには?

個々の文字/数字の代わりに括弧を使用してパターンを一致させるには?

MSG私のパスから除外して、括弧を使用してシェルパラメータ拡張を使用したいと思いますPDFDOC

MSG括弧の間に入れるとM削除されず、削除のみとなりますMSG。インターネットを見てドキュメントを読んでいますが、まだこれを正しく行う方法を理解できません。たぶん私が検索するのに適したキーワードを知らないかもしれません。

私のコードはMSGのみを削除します。

find "${INPUTPATH}" -mindepth 2 -maxdepth 2 -type d -print0 | while IFS= read -r -d '' file; do
    echo "${file}"
    casenumber="${file#${INPUTPATH}/[MSG]}"
    echo "${casenumber}"
done

入力する:

/home/user/output/test/PDF/2218-0
/home/user/output/test/PDF/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/MSG/2226-4
/home/user/output/test/MSG/2226-4
/home/user/output/test/MSG/2222 -2
/home/user/output/test/MSG/2222 -2
/home/user/output/test/MSG/2218-0
/home/user/output/test/MSG/2218-0

現在のMSGを削除する出力:

/home/user/output/test/PDF/2218-0
/home/user/output/test/PDF/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/MSG/2226-4
SG/2226-4
/home/user/output/test/MSG/2222 -2
SG/2222 -2
/home/user/output/test/MSG/2218-0
SG/2218-0

予想出力:

/home/user/output/test/PDF/2218-0
/home/user/output/test/PDF/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/DOC/2218-0
/home/user/output/test/MSG/2226-4
/2226-4
/home/user/output/test/MSG/2222 -2
/2222 -2
/home/user/output/test/MSG/2218-0
/2218-0

実際にMSG、PDF、DOCをこのように削除したいと思います。

find "${INPUTPATH}" -mindepth 2 -maxdepth 2 -type d -print0 | while IFS= read -r -d '' file; do
    echo "${file}"
    casenumber="${file#${INPUTPATH}/[MSG][PDF][DOC]/}"
    echo "${casenumber}"
done

上記のコードが機能しない理由を理解しています。ただし、これを行うには、まずMSGを解決する必要があります。

最終予想出力:

/home/user/output/test/PDF/2218-0
2218-0
/home/user/output/test/DOC/2218-0
2218-0
/home/user/output/test/MSG/2226-4
2226-4
/home/user/output/test/MSG/2222 -2
2222 -2
/home/user/output/test/MSG/2218-0
2218-0

答え1

[MSG]グローバルパターンは1文字MまたはSに一致しますGMSGDOCまたはを一致させるには、inまたはin kshをPDF使用できます。 bash は zsh glob 演算子をサポートしませんが、after を含む ksh 演算子のサブセットをサポートしているため、bash では次のようになります.(MSG|DOC|PDF)zsh@(MSG|DOC|PDF)shopt -s extglob

shopt -s extglob
casenumber=${file#"${INPUTPATH}"/@(MSG|DOC|PDF)}

に割り当てられ、内容に一致する最短の先行部分を削除しcasenumber(文字通りzshとは異なり、ksh / bashで必要な周辺引用符のおかげで)、またはが続きます。$file$INPUTPATH/MSGDOCPDF

shopt -s extglobkshではbashに固有のもので、kshでは必要ない項目を省略してください。 zshから:

casenumber=${file#$INPUTPATH/(MSG|DOC|PDF)}

答え2

実際にワイルドカードではありませんが...

=~拡張テスト角かっこ内で使用すると、最新バージョンのBashはRegEx演算子を使用して正規表現ベースの一致を実行できます[[ ... ]]。キャプチャグループを実行でき、0番目のインデックスが1つのインデックスの下の完全一致を参照する組み込み(...)配列があります。最初のキャプチャグループの一致を参照し、次は2番目のキャプチャグループの一致を参照する式です。BASH_REMATCH${BASH_REMATCH[0]}${BASH_REMATCH[1]}${BASH_REMATCH[2]}

したがって、次のようにすることができます。

$ printf '%s\0' "/home/user/output/test/PDF/2218-0" "/home/user/output/test/DOC/2218-0" "/home/user/output/test/MSG/2226-4" |
while IFS= read -r -d '' file; do
  [[ "$file" =~ .*(DOC|MSG|PDF)(.*) ]] && printf '%s\n' "$file" "${BASH_REMATCH[2]}"
  done
/home/user/output/test/PDF/2218-0
/2218-0
/home/user/output/test/DOC/2218-0
/2218-0
/home/user/output/test/MSG/2226-4
/2226-4

答え3

正確な質問に答えるのではなく、この特定のケースに関するいくつかの注意事項です。

現在の場所にあることを考慮すると、生成されたすべてのパスにはfind "${INPUTPATH}" -mindepth 2 -maxdepth 2最初のパスの後に1つのスラッシュしか含まれていないため、$INPUTPATHそこにある3文字の文字列を無視して次の文字列の前のすべての項目を削除するだけです/

casenumber=${file#"${INPUTPATH}"/*/}

または最後のスラッシュなので、単に削除してください。すべて最後まで/:

casenumber="${file##*/}"

ここで2倍にすることは、#最も長い試合をすることを意味します。

また、以前に実行した場合は、$INPUTPATH出力から該当する部分を削除することもできます(次のように置き換えるだけです)。.cdfind

(cd -P -- "${INPUTPATH}" && find . -mindepth 2 -maxdepth 2 -type d -print0) |
 while IFS= read -r -d '' file; do
    echo "${file}"
    casenumber="${file#./*/}"
    echo "${casenumber}"
done

関連情報