以下简单版本控制脚本用于查找给定文件的最后版本号,递增它,使用新创建的文件(例如编辑器)运行给定命令,然后将其保存为稳定版本。由于它很简单,因此不会检查任何内容,因为脚本会根据需要进行修改。例如,如果结果不稳定,则用户可以省略最后一个参数。
但是,当前功能的一个主要问题是如何实现以下内容:如果dot之后的最后一个部分有两个数字,则包括直到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
剩下的问题是它不会等待标签式葡萄酒编辑器关闭文件;目标是检测标签何时关闭。另外,您能解释一下如何最好地确保我的变量名称不会覆盖现有的变量名称吗?
您还可以提供其他改进。
#!/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
更新:
#!/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,".") 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",(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