使用 SED 仅验证四位数字

使用 SED 仅验证四位数字

在 SED 命令中,我只希望 SED 在存在SOMETHING_4DigitsHereOnly_SOMETHING2.

例如,如果文件名是ITALY_2022_BEST1FRIENDS2_ROME.txt.我只想要2022_BEST1FRIENDS2,但如果它被命名,ITALY_202345_BEST1FRIENDS2_ROME.txt那么它应该给出一个错误,因为它不是 4 位数字,而是超过 4 位。如果没有找到该模式,我想在 shell 脚本中给出一个错误。

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 talk 要困难得多。对于大多数事情我更喜欢 awk。

鉴于此,您的问题的一种解决方案是以下脚本,正如您所看到的,它可以使逻辑更加明确以遵循(如果您只是长时间重新访问该代码,那么这是代码可维护性的关键):

#!/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

相关内容