SEDコマンドから2000_SOMENAME以降のすべてのエントリを削除し、可能であればフォーマットが見つからない場合はエラーも表示したいと思います。
たとえば、ファイル名が.の場合、パターンが見つからない場合は、シェルスクリプトでエラーを表示したいとITALY_2022_BEST1FRIENDS2_ROME.txt
思います。2022_BEST1FRIENDS2
username=$(find . -iname '*.txt' | sed -e 's/.*_\([0-9]\{4\}_[0-9|A-z]*\).*/\1/i' | sort - | uniq -ui |tr -d '\n')
以前の質問と詳細についてはこちらをご覧ください。SEDを使用したファイル名の一部の抽出 ありがとうございます! !
答え1
この特別なケースでは、grep -o
sedよりもgrepを使用する方が合理的かもしれません。結果がない場合は、grepがエラーで終了するためです。 (これを-o
行うと、行全体ではなく一致する部分のみが返されます。)
難しいのは、別のコマンドでパイプを接続し、エラーが発生した場合にシャットダウン状態を維持することです。
Bashを使用すると、コンポーネントが失敗するとパイプラインが失敗する可能性がありますset -o pipefail
(set +o pipefail
必要に応じてリセットしてリセットできます)。
他のシェルにも同様の方法があります。
set -o pipefail
username="$(find . -iname '*.txt' | grep -o -i '[0-9]\{4\}_[0-9A-Z]*' | sort - | uniq -ui |tr -d '\n')"
# get the exit status of the previous command
pipeexit="$?"
set +o pipefail
if [[ "$pipeexit" != 0 ]] ; then
echo "username not found" >&2
# line below quits the script; remove if you don't want that
exit "$pipeexit"
fi
私はあなたの指示に従ってパターンを大文字と小文字を区別しないようにし(-i
grepの場合はsedコマンドにありi
)、パイプラインの残りのコマンドを同じままにしました。理由があってこうやったようです。 (このtr
コマンドは疑わしいようです。なぜすべての結果を1行にまとめるのですか?)
「エラー」を確認するより簡単な方法を検討することもできます。変数が$username
空であることを確認し、grepの結果がない場合は空です(もちろんfindなどで.txtが見つからない場合)。ファイル)。 ;欲しいかどうかわからない...)。
username="$(find . -iname '*.txt' | grep -o -i '[0-9]\{4\}_[0-9A-Z]*' | sort - | uniq -ui |tr -d '\n')"
if [ -z "$username" ] ; then
echo "username not found" >&2
exit "$pipeexit"
fi
これは他のシェルでも動作する可能性が高いです。