如何在shell脚本中增加版本号?

2023-12-02

以下简单的版本控制脚本旨在查找给定文件的最后版本号,递增它,使用新创建的文件(例如编辑器)运行给定命令,然后将其保存到稳定版本。由于它很简单,因此不会检查任何内容,因为脚本会根据需要进行修改。例如,如果结果不稳定,用户可以省略最后一个参数。

然而,当前功能的一个主要问题是如何实现以下功能:如果点后的最后一部分有两位数字,则一直到 99;如果只有 1,则递增到 9,然后移至上一节。这些版本可以具有任意正整数数量的部分。

1.2.3.44 -> 1.2.3.45
1.2.3.9 -> 1.2.4.0
1.2.3 -> 1.2.4
9 -> 10

剩下的问题是它不会等待选项卡式 wine 编辑器关闭文件;目标是检测选项卡何时关闭。另外,您能否解释一下如何最好地确保我的变量名称不会覆盖现有的变量名称?

您还可以提供其他改进。

#!/bin/bash
#Tested on bash 4.1.5
#All arguments in order: "folder with file" "file pattern" cmd [stable name]
folder="$1"
file_pattern="$2"
cmd="$3"
stable="$4"

cd "$folder"
last_version=$(ls --format=single-column --almost-all | \
    grep "$file_pattern" | \
    sed -nr 's/^[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/p' | \
    sort -Vu | \
    tail -n 1)
last_version_file=$(ls --format=single-column --almost-all | \
    grep "$file_pattern" | \
    grep $last_version | \
    tail -n 1) #tail -n 1 is only needed to get 1 line if there are backup files with the same version number
new_version=$(echo $last_version | \
    gawk -F"." '{$NF+=1}{print $0RT}' OFS="." ORS="") #increments last section indefinitely
new_version_file=$(echo "$last_version_file" | \
    sed -r "s/$last_version/$new_version/")
cp "$last_version_file" "$new_version_file"
"$cmd" "$new_version_file" & \
    wait #works with gedit but not with wine tabbed editor
[[ "$stable" ]] && \
    cp "$new_version_file" "$stable" #True if the length of string is non-zero.

更新: 以下内容在我的电脑上有效,如果发现改进或未解决问题的解决方案,我将更新它:

#!/bin/bash
inc()
{
shopt -s extglob
    num=${last_version//./}
    let num++

    re=${last_version//./)(}
    re=${re//[0-9]/.}')'
    re=${re#*)}

    count=${last_version//[0-9]/}
    count=$(wc -c<<<$count)
    out=''
    for ((i=count-1;i>0;i--)) ; do
        out='.\\'$i$out
    done

    sed -r s/$re$/$out/ <<<$num
}

folder="$1"
file_pattern="$2"
cmd="$3"
stable="$4"

cd "$folder"
last_version=$(ls --format=single-column --almost-all | \
    grep "$file_pattern" | \
    sed -nr 's/^[^0-9]*(([0-9]+\.)*[0-9]+).*/\1/p' | \
    sort -Vu | \
    tail -n 1) #--almost-all do not list implied . and ..
last_version_file=$(ls --format=single-column --almost-all | \
    grep "$file_pattern" | \
    grep $last_version | \
    tail -n 1) #tail -n 1 is only needed to get 1 line if there are backup files with the same version number
new_version=$(inc)
new_version_file=$(echo "$last_version_file" | \
    sed -r "s/$last_version/$new_version/")
cp "$last_version_file" "$new_version_file"
"$cmd" "$new_version_file" && \
    wait #works with gedit but not tabbed wine editor
[[ "$stable" ]] && \
    cp "$new_version_file" "$stable" #True if the length of string is non-zero.

我很欣赏所提供的各种解决方案,因为它们有助于获得观点并进行比较。


$ echo 1.2.3.4 | awk -F. -v OFS=. 'NF==1{print ++$NF}; NF>1{if(length($NF+1)>length($NF))$(NF-1)++; $NF=sprintf("%0*d", length($NF), ($NF+1)%(10^length($NF))); print}'
1.2.3.5

1.2.3.9  => 1.2.4.0
1.2.3.44 => 1.2.3.45
1.2.3.99 => 1.2.4.00
1.2.3.999=> 1.2.4.000
1.2.9    => 1.3.0
999      => 1000

UPDATE:

#!/usr/bin/gawk -f

BEGIN{
    v[1] = "1.2.3.4"
    v[2] = "1.2.3.44"
    v[3] = "1.2.3.99"
    v[4] = "1.2.3"
    v[5] = "9"
    v[6] = "9.9.9.9"
    v[7] = "99.99.99.99"
    v[8] = "99.0.99.99"
    v[9] = ""

    for(i in v)
        printf("#%d: %s => %s\n", i, v[i], inc(v[i])) | "sort | column -t"
}

function inc(s,    a, len1, len2, len3, head, tail)
{
    split(s, a, ".")

    len1 = length(a)
    if(len1==0)
        return -1
    else if(len1==1)
        return s+1

    len2 = length(a[len1])
    len3 = length(a[len1]+1)

    head = join(a, 1, len1-1)
    tail = sprintf("%0*d", len2, (a[len1]+1)%(10^len2))

    if(len2==len3)
        return head "." tail
    else
        return inc(head) "." tail
}

function join(a, x, y,    s)
{
    for(i=x; i<y; i++)
        s = s a[i] "."
    return s a[y]
}

$ chmod +x inc.awk
$ ./inc.awk
#1:  1.2.3.4      =>  1.2.3.5
#2:  1.2.3.44     =>  1.2.3.45
#3:  1.2.3.99     =>  1.2.4.00
#4:  1.2.3        =>  1.2.4
#5:  9            =>  10
#6:  9.9.9.9      =>  10.0.0.0
#7:  99.99.99.99  =>  100.00.00.00
#8:  99.0.99.99   =>  99.1.00.00
#9:  =>           -1
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在shell脚本中增加版本号? 的相关文章

  • 如何从 C 文件更改终端中的目录

    如何从 C 程序更改将在终端上生效的目录 实际上不要告诉 system 函数或 chdir 函数 这些仅适用于 C 中的进程或子 shell 假设我正在从 bash shell 执行一个 C 程序 其进程 ID 为 10223 那么 我可以
  • Bash:查找并连接文件

    我有以下结构 home DIR1 file ab csv DIR2 file cd csv DIR3 file3 ef csv Where file csv包含多行浮点数 每个 DIR 都有不同的浮点数 我想抓取所有的内容file csv文
  • Bash 中的 Shellshock 漏洞背后的行为是有记录的还是有意为之?

    最近的一个漏洞 CVE 2014 6271 http web nvd nist gov view vuln detail vulnId CVE 2014 6271 如何Bash http en wikipedia org wiki Bash
  • 如何“grep”连续流?

    可以用吗grep在连续的流中 我的意思是有点tail f
  • 如何在Windows Git shell中运行./script.sh?

    也许这很尴尬 但是当我在 Git shell 中工作时 我无法在 Windows 上运行 sh 文件 也许我必须安装一些东西 但我认为 Git 会支持 bash 命令 我知道 Windows 不使用 sh 文件 我正在执行安装步骤游戏结束
  • 按行号和列号对文件进行子集化

    我们想要按行和列对文本文件进行子集化 其中行数和列数是从文件中读取的 不包括标题 第 1 行 和行名称 第 1 列 输入文件 txt制表符分隔的文本文件 header 62 9 3 54 6 1 25 1 2 3 4 5 6 96 1 1
  • 将所有脚本参数复制到另一个变量

    我需要复制所有脚本参数并将它们传递给另一个脚本 我尝试这样做 args printargs sh args echo printargs sh args 但在这种情况下 如果我使用包含空格的参数调用我的父脚本 例如 script sh ar
  • 通过 SSH 将变量传递给远程脚本

    我正在通过 SSH 从本地服务器在远程服务器上运行脚本 首先使用 SCP 复制该脚本 然后在传递一些参数时调用该脚本 如下所示 scp path to script server example org another path ssh s
  • 找不到 NGINX brew 安装命令

    I do brew install nginx and get gt Downloading http nginx org download nginx 1 2 2 tar gz Already downloaded Library Cac
  • Bash 脚本 - 迭代 find 的输出

    我有一个 bash 脚本 其中需要迭代 find 命令输出的每一行 但似乎我正在迭代 find 命令中的每个单词 以空格分隔 到目前为止我的脚本看起来像这样 folders find maxdepth 1 type d for i in f
  • bash 自动完成:添加可能完成的描述

    是否可以使 bash 自动完成功能看起来像 Cisco IOS shell 中一样 我的意思是为每个完成添加简短的描述 如下所示 telnet 10 10 10 TAB Pressed 10 10 10 10 routerA 10 10 1
  • 别名在 Bash 脚本中不起作用[重复]

    这个问题在这里已经有答案了 我有一个可执行文件command sh bin bash alias my command echo ok my command 我的终端是bash 当我像这样运行时 command sh 效果很好 当我像这样运
  • 从 Ruby 运行 shell 命令:在显示输出时捕获输出?

    我有个问题 我想从另一个 ruby 脚本运行一个 ruby 脚本并捕获它的输出信息 同时让它也输出到屏幕上 runner usr bin env ruby print Enter your password password gets ch
  • CentOS目录结构是树形的吗?

    CentOS 上有相当于树的东西吗 如果你的 Centos 系统上没有安装 tree 无论如何我通常建议服务器设置使用最小安装磁盘 你应该在命令行中输入以下内容 yum install tree y 如果没有安装 那是因为您没有正确的存储库
  • BASH 脚本编译多个 C++ 文件 - OpenCV

    请参见在C 和OpenCV中调用其他文件中的函数 https stackoverflow com questions 24442836 call functions in other files in c and opencv 对于最初的问
  • “grep -q”的意义是什么

    我正在阅读 grep 手册页 并遇到了 q 选项 它告诉 grep 不向标准输出写入任何内容 如果发现任何匹配 即使检测到错误 也立即以零状态退出 我不明白为什么这可能是理想或有用的行为 在一个程序中 其原因似乎是从标准输入读取 处理 写入
  • Python3 http.server:将日志保存到文件中

    我使用Python3 6编写了一个简单的HTTP服务器来重定向所有请求 我写的文件可以找到here https github com kmahyyg learn py3 blob master antiscanhttp py 我可以在 Ub
  • 如何将命令作为参数传递给 ssh [重复]

    这个问题在这里已经有答案了 我的需要是让这个命令起作用 sshpass p XXXX ssh oStrictHostKeyChecking no email protected cdn cgi l email protection sudo
  • 设置 Pyenv 的路径

    我正在尝试在我的服务器中设置 Pyenv 的加载路径 bashrc file 我正在关注这个tutorial https realpython com intro to pyenv 它要求我们在哪里设置pyenv到加载路径 然而 在我的 b
  • 规范化 solaris 上的路径名

    在 GNU 系统上我只会使用readlink f SOME PATH 但 Solaris 没有 readlink 我更喜欢在 bash 中运行良好的程序 但如果需要的话其他程序也可以 Edit 到目前为止 我想到的最好的方法是使用 cd 和

随机推荐

  • 为什么使用“for”循环在程序中添加两次“int”标签时输出不同?

    我是一名学习者 也是 C 语言的新手 当我创建一个使用 for 循环给出两个数字的幂的函数时 我遇到了在循环开始之前使用 int 声明以及在循环中更改程序输出的情况 为什么会这样呢 使用 int 声明一次的代码具有正确的输出 include
  • Android:在Activity之间传递哈希图

    我有一个字符串和类对象之间的映射 我在活动 1 中填充此地图 并希望将其传递给活动 2 public class NEW extends Activity public class data String name float value
  • Chrome 扩展 - 在内容脚本中接收请求

    有没有更好的方法在内容脚本和弹出窗口 背景之间传递命令 现在我正在做这样的事情 而且它不可维护或不健壮 chrome runtime onMessage addListener request sender sendResponse gt
  • 自定义index.html javadoc页面?

    我正在使用 ant 任务运行 javadoc
  • MATLAB 到 Python 代码转换(NumPy、SciPy、MatplotLib?)

    我正在尝试将以下代码从 MATLAB 转换为 Python 以用于 EEG 项目 部分原因是 Python 稍微便宜一些 希望有人能指出我正确的方向 我已经开始改变它但陷入困境 特别是试图找到等效的功能 尝试过 scipy org NumP
  • 添加默认不可为空列时的 Oracle 错误

    我过去在 Oracle 11g 的各种实例中都遇到过这个错误 无法亲自访问 Oracle 支持来了解这是否是已识别 已解决的问题 该错误会导致查询始终返回列的默认值 即使记录实际上具有不同的值也是如此 它仅在特定查询中出现 并且是通过使用单
  • Excel / VBA - 使用动态范围的索引匹配函数

    如何有效地使用Index MatchVBA中的公式 背景 我有一个工作表 该工作表在很大程度上依赖于公式的使用 该公式根据将特定名称与其名称范围以及特定日期与其日期范围相匹配来检索输出 INDEX OutputRange MATCH 1 N
  • 如何计算两个日期之间的季度数

    问题一 您如何计算开始日期之间的季度数 base date变量 和ypandas 数据框中的列 from dateutil relativedelta import relativedelta import pandas as pd imp
  • 将锚标记替换为 span 或 div 或 p

    我有一个功能 一旦用户单击链接 就会发出 ajax 请求 如果发出请求 则该链接不应再单击 这是我用来完成此任务的方法 a id rsvp click function e e preventDefault post this data u
  • PHP - 多维数组差异

    我想请求你的帮助 因为我很难解决这个问题 我创建了一个函数来促进数组差异 但它不足以满足我的需求 谢谢 还有更多的力量
  • 设置 sbt 使用 Java 7 进行编译?

    我在运行时遇到编译错误compile任务 因为源引用了新类java nio file仅出现在 Java 7 中的包 我有以下内容build sbt javaHome Some file opt jdk jdk1 7 0 fork true
  • 重试之前的任务操作 TPL

    我想实现一个重试任务 该任务采用先前失败的任务操作并重复它 这是我到目前为止所拥有的 然而 它只是重复任务出错的事实 而不是再次实际触发任务的操作 public static async Task
  • Accept* HTTP 标头中的 q=0.5 是什么?

    Accept text html application xhtml xml application xml q 0 9 q 0 8 Accept Language en us en q 0 5 Accept Charset ISO 885
  • 如何在控制台项目中使用 Main() 启动窗口?

    我有一个控制台项目 但现在我需要放置一个用户界面 所以我使用 3 层模型 演示 业务 访问数据 按照我的方法Main 我调用的是表示层 比如Window形式的app或者Wpf 所以 在表示层就是通过CONSOLE与用户交互 现在 我在表示层
  • 运行 Android 应用程序时出现持续问题

    我在使用 Android 应用程序时遇到了非常困难的时期 我正在使用 Eclipse V 4 2 0 并运行 API 版本 7 下面是我遇到困难的一个程序的 LogCat 输出 这是我的代码 Manifest
  • Selenium WebDriver 和 Selenium 服务器

    我需要你的帮助来连接与硒相关的东西 在过去的几周里 我一直在阅读有关 Selenium 的文档 有selenium IDE 用于记录和重放测试的firefox扩展 硒 RC 硒 1 0 现在似乎已弃用 并使用代理 HTTP 服务器在多个浏览
  • IOS JSON 反序列化失败 - STIG/NSJSONSerializer

    我想反序列化从 IOS 中运行的 Web 服务收到的简单 JSON NickName James Roeiter3 TempId 634783760669935686 LDAP XUserName15 SecToken null NickN
  • OPENGL用户界面编程[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 目前不接受答案 我正在开发一个图形应用程序来呈现数据 不是游戏 而是真正的主力应用程序 它需要跨平台 所以我选择了 python openGL 我需要 3D 混合
  • Excel VBA 循环遍历数据透视项

    我想循环遍历我的数据透视项并检查它们是否存在于另一个表中 请参阅我的示例屏幕截图 所以我想循环遍历所有颜色 检查它们是否存在于另一个表中 例如在另一个表中 有什么办法可以做到这一点 这样就会出现一个消息框 提示在列表中找不到紫色 非常感谢您
  • 如何在shell脚本中增加版本号?

    以下简单的版本控制脚本旨在查找给定文件的最后版本号 递增它 使用新创建的文件 例如编辑器 运行给定命令 然后将其保存到稳定版本 由于它很简单 因此不会检查任何内容 因为脚本会根据需要进行修改 例如 如果结果不稳定 用户可以省略最后一个参数