递增一个数字,问题从 19 变为 20,因为它变成了 110

Incrementing a number, problem in change from 19 to 20, as it turns it into 110 instead

提问人:ReaderGuy42 提问时间:10/28/2023 最后编辑:John KugelmanReaderGuy42 更新时间:10/28/2023 访问量:66

问:

我有一个脚本,我一直在用它来递增文件名。这些文件的名称类似于“YYYY-MM-DD name V. 23”。只要没有跳到下一个 10 个,它就很好用,这就是为什么到目前为止我还没有注意到问题的原因。但是当它移动到下一个 10 时,它似乎看不到整数,而只看到最后一个数字。它与 Bash-Rematch 有关,但我无法弄清楚。

#!/bin/bash

fileName=$1

today=$(date +"%Y-%m-%d")


if [[ $fileName =~ ([0-9]+-[0-9]+-[0-9]+)(.*)([0-9]+)\.([^.]*) ]]; then
  # BASH_REMATCH match groups:
  # 1 - date
  # 2 - everything else
  # 3 - number
  # 4 - extension

  number=$(( ${BASH_REMATCH[3]} + 1 ))

  while :; do
        newFileName="$(date +%Y-%m-%d)${BASH_REMATCH[2]}${number}.${BASH_REMATCH[4]}"
        [[ -f $newFileName ]] || break
        let "number++"
  done

  echo "copy $fileName to $newFileName"
  cp "$fileName" "$newFileName"

elif [[ $fileName =~ (.*)\.([^.]*) ]]; then
    newNumber="1"
    addInfoName="$today ${BASH_REMATCH[1]} V.${newNumber}.${BASH_REMATCH[2]}"

    mv "$fileName" "$addInfoName" 
    let "newNumber++"
    cp "$addInfoName" "$today ${BASH_REMATCH[1]} V.${newNumber}.${BASH_REMATCH[2]}"
fi

该脚本应该检查文件开头的日期是否是今天的日期(如果在复制文件时没有更改),然后查看末尾是否有数字(如果没有添加一个)并将该数字递增 1。

例如,如果我触发脚本,它会变成2023-09-25 Letter Application V.32023-10-28 Letter Application V.4

我如何让脚本考虑末尾的整数(例如),以便它变成下一个 10(例如 而不是)?2930210

ChatGPT 和类似组织建议在正则表达式字段中的数字周围添加 [[:space:]](例如),但这会导致数字(和开头的日期)根本无法识别,因此它看起来像([0-9]+-[0-9]+-[0-9]+)(.*)([[:space:]][0-9]+[[:space:]])(\.[^.]*)$2023-10-28 2023-09-25 Letter Application V. 29 V. 1

bash 文件重命名

评论

2赞 cornuz 10/28/2023
..这就是为什么人们应该停止认为 ChatGPT 可以编码的原因。
1赞 ChrisB 10/28/2023
您的代码和正则表达式假定在扩展之前存在一个组件,但您的示例 () 在扩展之前没有这样的数字部分。请澄清您实际想要什么,并可能在您:)时将呈现的代码缩短为相关部分。number2023-09-25 Letter Application V.3

答:

1赞 cornuz 10/28/2023 #1

在我看来,您的问题与 2 位数字无关。RE 与您指示的字符串模式不匹配。

  • 您的字符串模式:YYYY-MM-DD name V. 23
  • 您的回复:([0-9]+-[0-9]+-[0-9]+)(.*)([0-9]+)\.([^.]*)

根据 RE,字符串以 结尾,这是不正确的。number.extension

我认为您需要的 RE 是.([0-9]+-[0-9]+-[0-9]+)\s+(.+)\s+V\.\s+([0-9]+)

检查演示

请注意,我用PCRE测试了这一点,您可能需要替换为:\s[[:space:]]

([0-9]+-[0-9]+-[0-9]+)[[:space:]]+(.+)[[:space:]]+V\.[[:space:]]+([0-9]+)

评论

0赞 ReaderGuy42 10/29/2023
谢谢!这最终是我的 RE: ' ([0-9]+-[0-9]+-[0-9]+)(.+)[[:空格:]]([0-9]+)\。([^.]*)',因为在我的示例中,我忘记了我确实需要的扩展。我试过删除它,但后来它坏了,又做了这件事(19->110)。你知道为什么会这样吗?[[:space:]]
0赞 glenn jackman 10/29/2023
问题是 是贪婪的,会啜饮数字(除了最后一个强制执行的数字)。你不能让第二个项比第一个项更贪婪,除非限制第一个项的匹配:你可能想要。或者接受在两个术语之间放置一个空格是有效的(.+)([0-9]+)(.+)([0-9]+)([^0-9]+)([0-9]+)