bash循环中的多个变量

时间:2013-01-10 21:19:30

标签: bash svn

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

这个svn命令

$ svn status /myLocalDir/files

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

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

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

一个。打印出“删除”[X]或“添加”[X]

B中。如果我应该将循环中的当前文件删除或添加到svn中,则根据第一个char(?,!)确定。

我只是不确定如何解析字符串“!/ 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

5 个答案:

答案 0 :(得分: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返回的状态代码,并在此框架中放置您需要的代码来代替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 )

答案 1 :(得分: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

答案 2 :(得分: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 

答案 3 :(得分:0)

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

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

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

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

答案 4 :(得分: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"