Der Schrägstrich im Bash-Skript für die Verwendung mit sed wird ordnungsgemäß ausgeblendet

14

Ich versuche, die Größe der Dateien zu bestimmen, die beim Synchronisieren von zwei Ordnern neu kopiert werden, indem ich rsync im trockenen Modus ausführe und dann die Größe der in der Ausgabe von rsync aufgelisteten Dateien aufsummiere.

Derzeit stecke ich fest, ob ich den Dateien den übergeordneten Ordner voranstelle. Ich fand heraus, wie man mit sed Zeilen voranstellt und mit sed entkommt, aber ich habe Probleme, diese beiden zu kombinieren.

So weit bin ich gekommen:

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}'

Dies ist die Ausgabe, die ich von bash -x myscript.sh bekomme

+ 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

Irgendwelche Ideen, wie man richtig entkommt, wären hoch geschätzt.

user331839
quelle

Antworten:

27

Sie brauchen sich eigentlich nicht darum zu kümmern, dem zu entkommen /. Sie können stattdessen ein beliebiges anderes einzelnes Zeichen verwenden. Beispielsweise:

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

gibt die Ausgabe

barbar
jjlin
quelle
4
Dies sollte das erste , was in der Manpage für sed sein
Clearer
Beliebig wie in 'Beliebig' *?
Ujjwal Singh
0

Wenn Sie versuchen, die Daten zu erfassen, möchten Sie wahrscheinlich alle möglichen Unterverzeichnisse überspringen. Dies ist möglicherweise nicht zutreffend, aber es ist immer am besten, jegliche Verrücktheit zu vermeiden. Hier ist mein Quellverzeichnis. Diese Dateien wurden alle mit Touch erstellt und belegen daher 0 Speicherplätze.

$ find source
source
source/5832
source/5832/5832_1.png
source/5832/5832_2.png
source/5831
source/5831/5831_1.png
source/5830
source/5830/5830_3.png
source/5830/5830_1.png
source/5830/5830_2.png

Sie sollten nicht in der Nähe von so viel entkommen müssen, wie Sie tun. Der Sed Block hier macht folgendes:
1d; lösche die erste Zeile von 'send incremental file list'
/ ^ $ /, $ d; Löschen Sie die leere Zeile, die das Ende der Dateiliste und alles, was danach steht, kennzeichnet.
// $ / d löscht alle Zeilen, die mit einem '/' enden. Dies wären die Verzeichnisse.
Beachten Sie, dass Sie die Schrägstriche mit Backslashes umgehen können (um die eigentliche Frage zu beantworten).

$ du $(rsync -ahnv source target | sed '1d;/^$/,$d;/\/$/d')
0   source/5830/5830_1.png
0   source/5830/5830_2.png
0   source/5830/5830_3.png
0   source/5831/5831_1.png
0   source/5832/5832_1.png
0   source/5832/5832_2.png

Und für zusätzliche Bonuspunkte können Sie die Ergebnisse sogar zusammenfassen:

$ du -s $(rsync -ahnv source target | sed '1d;/^$/,$d;/\/$/d') | awk '{x+=$1;print $0} END {print "sum: "x}'
0   source/5830/5830_1.png
0   source/5830/5830_2.png
0   source/5830/5830_3.png
0   source/5831/5831_1.png
0   source/5832/5832_1.png
0   source/5832/5832_2.png
sum: 0

Wenn Sie dies mit dem bereits vollständig synchronisierten Verzeichnis tun, werden jedoch lustige Ergebnisse zurückgegeben:

76  .
sum: 76
Falsche Namen
quelle