web-dev-qa-db-ja.com

sedで使用するためにbashスクリプトでスラッシュを適切にエスケープする

ドライモードでrsyncを実行し、rsyncの出力にリストされているファイルのサイズを合計して、2つのフォルダーを同期するときに新しくコピーされるファイルのサイズを特定しようとしています。

現在、私は親フォルダーによってファイルのプレフィックスを付けることに行き詰まっています。 sedを使用して行にプレフィックスを付ける方法とsedを使用してエスケープする方法を見つけましたが、これら2つを組み合わせるのに問題があります。

これは私がどこまで得たかです:

source="/my/source/folder/"
target="/my/target/folder/"
escaped=`echo "$source" | sed -e 's/[\/&]/\\//g'`
du `rsync -ahnv $source $target | tail -n +2 | head -n -3 | sed "s/^/$escaped/"` | awk '{i+=$1} END {print i}'

これは、bash -x myscript.shから取得した出力です

+ source=/my/source/folder/
+ target=/my/target/folder
++ echo /my/source/folder/
++ sed -e 's/[\/&]/\//g'
+ escaped=/my/source/folder/
+ awk '{i+=$1} END {print i}'
++ rsync -ahnv /my/source/folder/ /my/target/folder/
++ sed 's/^//my/source/folder//'
++ head -n -3
++ tail -n +2
sed: -e expression #1, char 8: unknown option to `s'
+ du
80268

適切に脱出する方法についてのアイデアは高く評価されます。

14
user331839

実際に/をエスケープする必要はありません。 GNU sed manual から:

/文字は、任意のsコマンド内で、他の単一の文字に均一に置き換えることができます。

例えば:

echo 'foobar' | sed -e 's#foo#bar#'

出力を与える

barbar
28
jjlin