Escape slash ไปข้างหน้าอย่างถูกต้องใน bash script เพื่อใช้กับ sed


14

ฉันกำลังพยายามกำหนดขนาดของไฟล์ที่จะถูกคัดลอกใหม่เมื่อทำการซิงค์สองโฟลเดอร์โดยการเรียกใช้ rsync ในโหมดแห้งแล้วรวมขนาดของไฟล์ที่แสดงในเอาต์พุตของ rsync

ขณะนี้ฉันติดอยู่ที่คำนำหน้าไฟล์โดยโฟลเดอร์แม่ของพวกเขา ฉันค้นพบวิธีนำหน้าบรรทัดโดยใช้ sed และวิธีหลบเลี่ยงการใช้ sed แต่ฉันมีปัญหาในการรวมสองรายการนี้

นี่เป็นวิธีที่ฉันได้รับ:

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

ความคิดใด ๆ เกี่ยวกับวิธีการหลบหนีอย่างถูกต้องจะได้รับการชื่นชมอย่างมาก

คำตอบ:


28

/คุณไม่จริงต้องรำคาญกับการหลบหนี จากคู่มือGNUsed :

/ตัวอักษรอาจถูกแทนที่อย่างสม่ำเสมอโดยตัวละครอื่น ๆ เดียวภายในใดก็ตามsคำสั่ง

ตัวอย่างเช่น:

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

ให้ผลลัพธ์

barbar

4
นี่ควรเป็นสิ่งแรกในหน้า man สำหรับ sed
Clearer

มีอะไรบ้างใน 'any' *?
Ujjwal Singh

0

หากคุณกำลังพยายามรวบรวมข้อมูลคุณอาจต้องข้ามไดเรกทอรีย่อยที่เป็นไปได้ทั้งหมด สิ่งนี้อาจใช้ไม่ได้ แต่เป็นการดีที่สุดที่จะหลีกเลี่ยงความแปลกประหลาด นี่คือไดเรกทอรีต้นทางของฉัน ไฟล์เหล่านี้ถูกสร้างขึ้นทั้งหมดด้วยการสัมผัสดังนั้นพวกเขาจึงใช้พื้นที่ 0

$ 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

คุณไม่จำเป็นต้องหลบหนีไปทุกที่ใกล้เท่าที่คุณกำลังทำ บล็อก sed ที่นี่จะทำสิ่งต่อไปนี้:
1d; ลบบรรทัดแรกของ 'การส่งรายการไฟล์ที่เพิ่มขึ้น'
/ ^ $ /, $ d; ลบบรรทัดว่างที่บ่งบอกถึงจุดสิ้นสุดของรายการไฟล์และทุกอย่างหลังจากนั้น
// $ / d ลบบรรทัดใด ๆ ที่ลงท้ายด้วย '/' ซึ่งจะเป็นไดเร็กตอรี่
โปรดทราบว่าคุณสามารถหลีกเลี่ยงเครื่องหมายทับด้วยแบ็กสแลช (เพื่อตอบคำถามจริง)

$ 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

และสำหรับคะแนนโบนัสพิเศษคุณสามารถสรุปผลลัพธ์ได้ดังนี้:

$ 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

หากคุณทำสิ่งนี้กับไดเรกทอรีที่ซิงค์ข้อมูลครบถ้วนแล้วมันจะส่งคืนผลลัพธ์ที่ตลก แต่:

76  .
sum: 76
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.