Meloloskan skrip bash ke depan dengan benar untuk penggunaan dengan sed

14

Saya mencoba menentukan ukuran file yang akan disalin baru ketika menyinkronkan dua folder dengan menjalankan rsync dalam mode kering dan kemudian merangkum ukuran file yang tercantum dalam output rsync.

Saat ini saya mandek pada awalan file oleh folder induknya. Saya menemukan cara untuk awalan garis menggunakan sed dan bagaimana cara melarikan diri menggunakan sed, tapi saya kesulitan menggabungkan keduanya.

Sejauh ini yang saya dapat:

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

Ini adalah output yang saya dapatkan dari 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

Setiap ide tentang cara melarikan diri dengan benar akan sangat dihargai.

pengguna331839
sumber

Jawaban:

28

Anda sebenarnya tidak perlu repot-repot melarikan diri /. Dari manual GNUsed :

The /karakter dapat seragam digantikan oleh karakter lain dalam setiap diberikan sperintah.

Sebagai contoh:

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

memberikan output

barbar
jjlin
sumber
4
Ini harus menjadi hal pertama dalam halaman manual untuk sed
Clearer
Any as in 'any' *?
Ujjwal Singh
0

Jika Anda mencoba untuk menghitung data, Anda mungkin ingin melewati subdirektori yang mungkin. Ini mungkin tidak berlaku, tetapi selalu yang terbaik untuk menghindari keanehan. Ini adalah direktori sumber saya. Semua file ini dibuat dengan sentuhan, sehingga membutuhkan 0 ruang.

$ 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

Anda tidak perlu melarikan diri sedekat yang Anda bisa. Blok sed di sini akan melakukan hal berikut:
1d; hapus baris pertama 'mengirim daftar file tambahan'
/ ^ $ /, $ d; hapus baris kosong yang menandakan akhir daftar file dan semuanya setelahnya.
// $ / d hapus sembarang baris yang diakhiri dengan tanda '/', yang akan menjadi direktori.
Perhatikan bahwa Anda dapat keluar dari garis miring dengan garis miring terbalik (untuk menjawab pertanyaan yang sebenarnya).

$ 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

Dan untuk poin bonus tambahan, Anda bahkan dapat menghitung hasilnya:

$ 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

Jika Anda melakukan ini dengan direktori yang sudah sepenuhnya disinkronkan, itu akan menghasilkan hasil yang lucu, meskipun:

76  .
sum: 76
Nama palsu
sumber