1

sed -e 's/OLD/NEW/g'フィルター (例: ) を svn プロパティ値に再帰的に適用したいと思います。

まず、単一のターゲットに対して、次のいずれかを実行できます。

  1. svn propget --strict PROPNAME TARGET | sed -e 's/OLD/NEW/g' | svn propset PROPNAME --file=- TARGET
  2. svn propset PROPNAME --file=<(svn propget --strict PROPNAME TARGET | sed -e 's/OLD/NEW/g') TARGET
  3. SVN_EDITOR="sed -i -e 's/OLD/NEW/g'" svn propedit PROPNAME TARGET
  4. svn propedit --editor-cmd "sed -i -e 's/OLD/NEW/g'" PROPNAME TARGET

どれが一番いいでしょうか?

1 または 2 について私が気に入らないのは、svn propget ... | sed ...パイプラインが失敗した場合svn propsetでも、おそらく空の標準入力で実行され、プロパティがリセットされることです。

一方、3 または 4 について私が気に入らないのは、フィルタリング コマンド ライン全体を引用して 1 つの文字列にする必要があることです。また、オプションに注意してください-i— フィルタリング コマンドは、ファイル パラメーターを取り、それをその場で編集する必要がありtrますawk

これらのいずれかに対するより良い代替案、または可能な改善策はありますか?

第二に、これを再帰的に行うにはどうすればよいですか?つまり、指定されたプロパティ PROPNAME を持つ特定の TARGET の下のすべてのターゲットで? すべてを 1 つのテキスト ストリームに連結するため、単に追加-Rすることはできません。私は次のようなことをしなければならないようです:svn propgetsvn propedit-R

svn proplist -R --only-with PROPNAME TARGET | while read target
do
    # do one of the above on "$target"
done

svn proplistと呼ばれるものはありません。--only-withその出力を簡単に解析して、プロパティを持つターゲットのみの名前を取得することはできません。

それを行う良い方法はありますか?

4

1 に答える 1

1

の出力svn propget -Rは簡単に解析できませんが、の出力はsvn propget -v -R解析できるので、一度実行して出力を解析することにしました。

最初にプロセス置換を試みましたが、このスレッド>(...)で尋ねられたように、そのようなサブプロセスの終了を強制または待機することができなかったため、出力メッセージは機能しましたが混乱していました。したがって、同じスレッドで回答されているように、私はコプロセスを使用しました。

#!/bin/bash
set -o errexit -o pipefail

if [ $# -le 2 ]; then
    echo "usage: $0 PROPNAME TARGET COMMAND [ARGS...]" >&2
    exit 1
fi
PROPNAME=$1; shift
TARGET=$1; shift
COMMAND=$1; shift

cleanup_and_wait() {
    if [[ ${COPROC[1]} =~ ^[0-9]+$ ]]; then
        eval "exec ${COPROC[1]}<&-"
        wait $COPROC_PID
    fi
}

unset curr_target
unset prev_line
while IFS= read -r line; do
    case "$line" in
    "    "*)
        line=${line:4}
        if declare -p prev_line >/dev/null 2>&1; then
            echo "$prev_line" >&${COPROC[1]}
        fi
        prev_line=$line
        ;;
    "  "*)
        line=${line:2}
        if [ "$line" != "$PROPNAME" ]; then
            echo "Unexpected property: $line" >&2
        fi
        cleanup_and_wait
        coproc { "$COMMAND" "$@" | svn propset "$PROPNAME" --file=- "$curr_target"; } >&2
        unset prev_line
        ;;
    "Properties on '"*"':")
        line=${line%"':"}
        line=${line#"Properties on '"}
        curr_target=$line
        ;;
    esac
done < <(svn propget --verbose --recursive "$PROPNAME" "$TARGET")
cleanup_and_wait

私が気に入らないマイナーな点の1つは、指定されたフィルターがプロパティ値を変更しない場合svn propsetでも、実行されて出力されることproperty 'PROPNAME' set on 'TARGET'です。プロパティ値が実際に変更されたターゲットのメッセージのみが表示されると便利です。

于 2012-06-21T20:17:43.290 に答える