Sfuggire correttamente alla barra rovesciata nello script bash per l'uso con sed


14

Sto cercando di determinare la dimensione dei file che verrebbero appena copiati quando si sincronizzano due cartelle eseguendo rsync in modalità dry e quindi riassumendo le dimensioni dei file elencati nell'output di rsync.

Attualmente sono bloccato nel prefisso dei file dalla loro cartella principale. Ho scoperto come prefissare le linee usando sed e come scappare usando sed, ma ho problemi a combinare quei due.

Questo è quanto lontano sono arrivato:

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

Questo è l'output che ottengo da 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

Qualsiasi idea su come fuggire correttamente sarebbe molto apprezzata.

Risposte:


28

In realtà non devi preoccuparti di sfuggire al /. Dal manuale GNUsed :

I /personaggi possono essere uniformemente sostituiti da qualsiasi altro singolo carattere all'interno di un dato scomando.

Per esempio:

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

dà l'output

barbar

4
Questa dovrebbe essere la prima cosa nella pagina man di sed
Clearer, il

Qualsiasi come in "qualsiasi" *?
Ujjwal Singh,

0

Se si sta tentando di eseguire il conteggio dei dati, è probabile che si desideri saltare tutte le possibili sottodirectory. Questo potrebbe non essere applicabile, ma è sempre meglio evitare qualsiasi stranezza. Ecco la mia directory di origine. Tutti questi file sono stati creati con il tocco, quindi occupano 0 spazio.

$ 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

Non dovresti aver bisogno di scappare da nessuna parte vicino tanto quanto stai facendo. Il blocco sed qui farà quanto segue:
1d; elimina la prima riga di "invio elenco file incrementale"
/ ^ $ /, $ d; elimina la riga vuota che indica la fine dell'elenco dei file e tutto il resto.
// $ / d elimina qualsiasi riga che termina con un '/', che sarebbe la directory
Nota che puoi sfuggire alle barre con barre rovesciate (per rispondere alla domanda reale).

$ 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 per ottenere punti bonus extra, puoi anche calcolare i risultati:

$ 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 lo stai facendo con la directory già completamente sincronizzata, restituirà risultati divertenti, sebbene:

76  .
sum: 76
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.