2

我正在编写一个 shell 脚本,它可以让我了解 svn 中目录的状态,然后循环遍历它并添加或删除文件。

这个 svn 命令

$ svn status /myLocalDir/files

返回我在本地添加或删除的文件。? = 添加,!= 已删除

!        /myLocalDir/files/deletedPicture.png
?        /myLocalDir/files/addedPicture.png

我在我的 bash 脚本中使用了一个循环(见下文)。我需要做的是,当我遍历已添加或删除的文件/文件夹的根目录时,我需要

A. 打印出“删除”[X]或“添加”[X]

B. 根据第一个字符 (?,!) 确定是否应该删除循环中的当前文件或将当前文件添加到 svn。

我只是不确定如何解析字符串“!/myLocalDir/files/deletedPicture.png”的语法来做到这一点

for X in `svn status /myLocalDir/files | cut -c 8-300`
            do  
                if [ "!" ]
                    then
                        echo "Deleting " $X
                        #svn $CREDENTIALS delete $X
                    else
                        echo "Adding " $X
                        #svn $CREDENTIALS  add $X
                fi

            done

我注意到的另一件事..甚至认为命令行中的 svn 状态

!        /myLocalDir/files/deletedPicture.png
?        /myLocalDir/files/addedPicture.png

我的 bash 循环回声是这样的

!        
/myLocalDir/files/deletedPicture.png
?
/myLocalDir/files/addedPicture.png
4

5 回答 5

3

X只会是一个字段,而不是一整行,你的代码的编写方式。试试这个:

while IFS= read -r status file; do
    case $status in
      \! )  echo "Deleting" ;;
      \? ) echo "Adding" ;;
      # etc.
    esac
done <( svn status /myLocalDir/files )

您可以改变模式以匹配返回的任何状态代码,并在此框架svn status中放置您需要的任何代码来代替s。echo

编辑:将 Josh 的代码添加到答案中以提供更好的格式:

while read -r line; do
    file="${line#????????}"        # Strip off the 7 flag columns and the separator
    status="${line%$file}"         # Get the 7 flags columns
    case "$status" in 
        '!'*) echo "Do something" ;;
        '?'*) echo "Do something else with $file";;
    esac
 done <( svn status /myLocalDir/files )
于 2013-01-10T21:45:42.450 回答
2

感谢所有的投入!!但这就是我所做的......我真正需要做的就是根据一个字符串的第一个字符确定基础,该字符被删除并被添加,所以我对它进行了子串化。我用破折号替换了空格,这解决了我的 for 循环问题,然后我根据我的条件对每个空格进行了子串化

for X in `svn status /myLocalDir/files |tr " " "-"`
            do  
                if [ ${X:0:1} == "!" ]
                    then
                        echo "Deleting " ${X:8}
                        svn delete ${X:8}
                    elif [ ${X:0:1} == "?" ]
                        echo "Adding " ${X:8}
                        svn add ${X:8}
                fi

            done
于 2013-01-10T22:31:17.567 回答
1

如果您只想检查第一个单词并将其余单词视为第二个单词,那么您可以这样做:

svn status /myLocalDir/files | while IFS= " " read -r line;
            do  
            read a b <<<$line

                if [ $a == "!" ]
                    then
                        echo "Deleting " "$b"
                        #svn $CREDENTIALS delete $b
                    else
                        echo "Adding " "$b"
                        #svn $CREDENTIALS  add $b
                fi
            done 
于 2013-01-10T21:27:28.760 回答
0

好的,你可以用更简单、更优雅(甚至可能更正确)的方式来做到这一点

  • 在一个命令中添加树中的所有新文件:(svn add --force /myLocalDir/files/*需要--force,因为已经有版本化文件,否则会产生警告“...已经在版本控制下”),也许它可以在没有--force的情况下使用,但是带有 -q 用于抑制输出
  • 带有用于添加|删除的管道的单行代码,没有大的 bashisms:

svn status | awk '/\?/ {print $2}' | xargs svn add

svn status | awk '/\!/ {print $2}' | xargs svn rm

于 2013-01-10T21:50:26.823 回答
0

编辑:为 stat 添加了所有可能的字段。查看svn help status它们的含义和价值。

treeConflict=" "
oldIFS="$IFS"
IFS=$'\n'
for line in $(svn stat "$path")
do 
   if [[ "$treeConflict" == "C" ]]; then
       continue # skip or handle tree conflict line
   fi

   operation="${line:0:1}"
   modifications="${line:1:1}"
   lock="${line:2:1}"
   history="${line:3:1}"
   external="${line:4:1}"
   repoLock="${line:5:1}"
   treeConflict="${line:6:1}"
   file="$(echo ${line} | sed "s#^.......##")"
done
IFS="$oldIFS"
于 2013-01-10T21:52:19.517 回答