Você não precisa se preocupar em escapar do /
. Você pode usar qualquer outro caractere único no lugar dele. Por exemplo:
echo 'foobar' | sed -e 's#foo#bar#'
fornece a saída
barbar
Estou tentando determinar o tamanho dos arquivos que seriam copiados recentemente ao sincronizar duas pastas executando o rsync no modo dry e, em seguida, somando os tamanhos dos arquivos listados na saída do rsync.
Atualmente, estou preso ao prefixar os arquivos por sua pasta pai. Eu descobri como prefixar linhas usando sed e como escapar usando sed, mas estou tendo problemas combinando esses dois.
Isto é o quão longe eu cheguei:
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}'
Esta é a saída que recebo do 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
Qualquer ideia de como escapar adequadamente seria muito apreciada.
Se você está tentando calcular os dados, provavelmente vai querer pular todos os subdiretórios possíveis. Isso pode não ser aplicável, mas é sempre melhor evitar qualquer estranheza. Aqui está o meu diretório de origem. Esses arquivos foram todos criados com toque, então eles ocupam 0 espaço.
$ 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
Você não deve precisar escapar em qualquer lugar perto do que está fazendo. O bloco sed aqui fará o seguinte:
1d; excluir a primeira linha de 'envio de lista de arquivos incrementais'
/ ^ $ /, $ d; exclua a linha em branco que significa o final da lista de arquivos e tudo depois dela.
// $ / d excluir qualquer linha que termine em '/', que seriam os diretórios
Note que você pode escapar das barras com barras invertidas (para responder à pergunta atual).
$ 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
E para pontos de bônus extras, você pode até calcular os resultados:
$ 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
Se você estiver fazendo isso com o diretório já totalmente sincronizado, ele retornará resultados engraçados:
76 .
sum: 76
Tags bash rsync sed linux bash-scripting