SEDコマンドでは、SEDのみが存在したいと思いますSOMETHING_4DigitsHereOnly_SOMETHING2
。
たとえば、ファイル名がITALY_2022_BEST1FRIENDS2_ROME.txt
。これが必要ですが、2022_BEST1FRIENDS2
名前が指定されている場合はITALY_202345_BEST1FRIENDS2_ROME.txt
4桁ではなく4桁を超えるため、エラーが発生します。パターンが見つからない場合は、シェルスクリプトでエラーを表示したいと思います。
username=$(find . -iname '*.txt' | sed -e 's/.*_\([0-9]\{4\}_[0-9|A-z]*\).*/\1/i' | sort - | uniq -ui |tr -d '\n')
grepコードは同じことをしますが、@frabjousユーザーのおかげでファイルが一致しないとエラーが発生します。
read filename
set -o pipefail
filename_trimmed=$(echo $filename | grep -o '[0-9]\{4\}_[0-9|A-z]*' -i | sort - | uniq -ui |tr -d '\n')
# get the exit status of the previous command
pipeexit="$?"
set +o pipefail
if [[ "$pipeexit" != 0 ]] ; then
echo "FILENAME not found" >&2
# line below quits the script; remove if you don't want that
exit "$pipeexit"
fi
echo trimmed mmc is $filename_trimmed
以前の質問と詳細についてはこちらをご覧ください。SEDを使用したファイル名の一部の抽出 SEDとREGEX抽出、パターンがない場合は拒否 ありがとうございます! !
ベストアンサー1
sed会話を理解するのははるかに難しいことがわかりました。私はほとんどの場合awkを好む。
これを考えると、問題に対する1つの解決策は次のスクリプトです。ご覧のとおり、従うべきロジックがより明確になります(長期間にわたってコードを再度訪問する場合、これはコードのメンテナンスの中心です。):
#!/bin/sh
BASE=`basename "$0" ".sh" `
TMP="/tmp/tmp.$$.${BASE}" ; rm -f "${TMP}"
START=`pwd`
REPORT="${START}/${BASE}.report" ; rm -f "${REPORT}"
if [ -n "${1}" ]
then
EVAL_DIR="$1"
else
EVAL_DIR="."
fi
############
#find "${EVAL_DIR}" -iname '*.txt' -print | sed 's+\.txt$++'
#exit 0
############
find "${EVAL_DIR}" -iname '*.txt' -print | sed 's+\.txt$++' | sort |
awk -F _ -v suf="txt" '\
function is_integer(x) {
if( index(x, ".") != 0 ){
return 0 ;
} ;
if( x + 0 == x && int(x) == x ){
return 1 ;
}else{
return 0 ;
} ;
}
! is_integer($2) {
printf("#ERROR|%s."suf"\n", $0 ) ;
}
length($2) == 4 {
for( i=2 ; i < NF ; i++ ){
printf("%s_", $i ) ;
} ;
print $NF ;
} ;
length($2) != 4 {
printf("#ERROR|%s."suf"\n", $0 ) ;
}' >"${REPORT}"
exit 0