วิธีการกรองไฟล์เมื่อใช้ scp เพื่อคัดลอก dir แบบวนซ้ำ?


99

ฉันต้องการคัดลอกไฟล์. class ทั้งหมดจากเซิร์ฟเวอร์ไปยังโลคัลโดยสงวนลิขสิทธิ์ทั้งหมด เช่นserver:/usr/some/unknown/number/of/sub/folders/me.classจะเป็น/usr/project/backup/some/unknown/number/of/sub/folders/me.classปัญหาคือมีไฟล์ไร้ประโยชน์อื่น ๆ อีกมากมายเช่นไฟล์. svn-base ที่ฉันไม่ต้องการ ฉันจะกรองไฟล์เหล่านี้เพื่อให้มี แต่scpไฟล์. class ได้อย่างไร


ฉันชอบตัวเลือก rsync ที่กล่าวถึง คุณไม่ได้ระบุว่านี่เป็นการดำเนินการเพียงครั้งเดียวหรือหากคุณจะดำเนินการนี้ซ้ำ ๆ โดยอัตโนมัติ สำหรับการดำเนินการแบบครั้งเดียวการใช้ find, grep -v, xargs และไฟล์ชั่วคราวอย่างรอบคอบควรใช้เวลาสั้น ๆ
user47559

คำตอบ:


152

ฉันอาจแนะนำให้ใช้สิ่งrsyncนี้เนื่องจากมีincludeและexcludeแฟล็กเช่น: -

rsync -rav -e ssh --include '*/' --include='*.class' --exclude='*' \
server:/usr/some/unknown/number/of/sub/folders/ \ 
/usr/project/backup/some/unknown/number/of/sub/folders/

ค่าสถานะที่เป็นประโยชน์อื่น ๆ :

  • -r สำหรับการเรียกซ้ำ
  • -a สำหรับไฟล์เก็บถาวร (ส่วนใหญ่เป็นไฟล์ทั้งหมด)
  • -v สำหรับเอาต์พุต verbose
  • -e เพื่อระบุ ssh แทนค่าเริ่มต้น (ซึ่งควรเป็น ssh จริง)

4
อย่างไรก็ตามเพื่อให้สิ่งนี้ละเว้นโฟลเดอร์ย่อยที่ไม่มีไฟล์คลาส * อยู่ในนั้น? (เช่นฉันไม่ต้องการไดร์ว่างเปล่า)
Grant Birchmeier

น่ากลัวและนี่ก็ชั่วร้ายเร็วเช่นกัน!
ปราสาทชลาสนี

2
คุณช่วยอธิบายได้
ไหม --include ไม่ใช่ --include

1
ตัวเลือก-aนี้มีอยู่แล้ว-rตาม rsync man pages
Georg Schölly

3
@GrantBirchmeier --prune-empty-dirsจะลบไดร์เปล่า ๆ
Elrond1337

75

ในการยกเว้น dotfiles ในไดเรกทอรีฐาน:

scp -r [!.]* server:/path/to/something

[!.]* คือเชลล์ลูกโลกที่ขยายไปยังไฟล์ทั้งหมดในไดเร็กทอรีการทำงานโดยไม่ขึ้นต้นด้วยจุด


10
นี่อาจเป็นคำตอบที่ดีที่สุด การใช้ globs เพื่อกรองไฟล์เป็นวิธีที่จะไป
Yoshua Wuyts

1
หากตัวเลือกของคุณถูก จำกัด ไว้ที่ scp เหมือนที่ฉันมีสิ่งนี้ช่วยได้แน่นอน
user28095

3
สิ่งนี้บ่งบอกถึงการยกเว้นไฟล์อย่างที่ถูกถาม แต่จะทำได้อย่างไรสำหรับทั้งไดเร็กทอรี
Pille

สำหรับ zsh:scp -r [\!.]* server:/path/to/something
Michael Bar-Sinai

37

ไม่มีคุณสมบัติใน scp ในการกรองไฟล์ สำหรับสิ่งที่ "ขั้นสูง" เช่นนี้ฉันขอแนะนำให้ใช้ rsync:

rsync -av --exclude '*.svn' user@server:/my/dir .

(บรรทัดนี้คัดลอก rsync จากโฟลเดอร์ที่ห่างไกลไปยังโฟลเดอร์ปัจจุบัน)

rsync tunnel เวอร์ชันล่าสุดผ่านการเชื่อมต่อ ssh โดยอัตโนมัติตามค่าเริ่มต้น


10

เนื่องจากคุณสามารถscpคุณควรจะตกลงที่จะssh,
สคริปต์อย่างใดอย่างหนึ่งดังต่อไปนี้หรือเข้าสู่ระบบและดำเนินการ ...

# After reaching the server of interest
cd /usr/some/unknown/number/of/sub/folders
tar cfj pack.tar.bz2 $(find . -type f -name *.class)

กลับไป (ออกจากระบบ) ไปยังเซิร์ฟเวอร์ในท้องถิ่นและscp,

# from the local machine
cd /usr/project/backup/some/unknown/number/of/sub/folders
scp you@server:/usr/some/unknown/number/of/sub/folders/pack.tar.bz2 .
tar xfj pack.tar.bz2

หากคุณพบว่า$(find ...)น้ำมันดินของคุณยาวเกินไปสำหรับการเปลี่ยนเป็น

find . -type f -name *.class | xargs tar cfj pack.tar.bz2

ในที่สุดเพราะคุณทำให้มันใน/usr/project/backup/,
ทำไมรำคาญสกัด? เพียงแค่เก็บไว้tar.bz2โดยอาจมีการประทับวันที่ + เวลา


สิ่งนี้ช่วยฉันได้ ฉันใช้ Windows และฉันกำลังต่อสู้พยายามติดตั้งrsyncและsshติดตั้งบนระบบปฏิบัติการ แต่นี่เป็นวิธีแก้ปัญหาที่ชาญฉลาด ขอบคุณ!
rayryeng

2

ด้านล่างคำสั่งสำหรับไฟล์

scp `ค้นหา. -maxdepth 1- ชื่อ "* .log" \! - ชื่อ "hs_err_pid2801.log" - พิมพ์ f` root @ IP: / tmp / test /

  1. IP จะเป็นที่อยู่ IP ของเซิร์ฟเวอร์ปลายทาง
  2. - ชื่อ "* .log" สำหรับรวมไฟล์
  3. \! - ชื่อ "hs_err_pid2801.log" สำหรับแยกไฟล์
  4. . เป็นผบ.
  5. - พิมพ์ f สำหรับประเภทไฟล์

ด้านล่างคำสั่งสำหรับไดเร็กทอรี

scp -r `ค้นหา. -maxdepth 1- ชื่อ "lo *" \! - ชื่อ "localhost" - ประเภท d` root @ IP: / tmp / test /

คุณสามารถปรับแต่งคำสั่งดังกล่าวได้ตามความต้องการของคุณ


1

เมื่อเปิดใช้งานการพิสูจน์ตัวตนโดยใช้คีย์ ssh สคริปต์ต่อไปนี้จะใช้งานได้

for x in `ssh user@remotehost 'find /usr/some -type f -name *.class'`; do y=$(echo $x|sed 's/.[^/]*$//'|sed "s/^\/usr//"); mkdir -p /usr/project/backup$y; scp $(echo 'user@remotehost:'$x) /usr/project/backup$y/; done

1

หากคุณต้องการใช้ scp จริงๆมีวิธีทางอ้อมสมมติว่าเราต้องการคัดลอกไฟล์. jpg ทั้งหมดภายใต้โฟลเดอร์ในเครื่อง '/ src' ไปยังโฟลเดอร์ '/ dst' ในเซิร์ฟเวอร์ระยะไกล 10.1.1.2:

#make a clean temp folder
mkdir /tmp/ttt
#copy all .jpg file and retain folder structure as-is
find /src -type f -name *.jpg -exec cp --parents \{\} /tmp/ttt \;
#copy to remote target folder as-is and retain original time attributes
scp -rp /tmp/ttt/* 10.1.1.2:/dst
#if copy ok, remove temp folder
rm -rf /tmp/ttt

0
scp -i /home/<user>/.ssh/id_rsa -o "StrictHostKeyChecking=no" -rp /source/directory/path/[!.]* <target_user>@<target_system:/destination/directory/path

1
คำอธิบายด้วยวาจายังมีประโยชน์พร้อมกับรหัส
คอน

-1
  1. คัดลอกโฟลเดอร์ต้นทางของคุณไปที่somedir:

    cp -r srcdir somedir

  2. ลบไฟล์ที่ไม่จำเป็นทั้งหมด:

    ค้นหา somedir -name '.svn' -exec rm -rf {} \ +

  3. เปิด scp จาก somedir


ทำไมการลงคะแนนทั้งหมดเกี่ยวกับคำตอบนี้? สิ่งนี้ดูเหมือนเป็นการแก้ปัญหาสำหรับคำถาม
bcarroll

7
เนื่องจากการทำเช่นนี้จะคัดลอกไฟล์ที่ไม่จำเป็นจำนวนมากจากนั้นจึงลบออกทำให้เสียเวลาไปมาก
Oded

สำหรับโปรแกรมที่ต้องผ่านขั้นตอนการคอมไพล์หลายขั้นตอนสิ่งนี้สมเหตุสมผลมาก มันสามารถไปก่อนขั้นตอนที่แพ็คโค้ดที่คอมไพล์แล้วลงในไฟล์tarหรือzip-file แต่ไม่มีการบีบอัด (scp ทำการบีบอัด) และโค้ด 'แพ็กเกจ' จะถูกคัดลอกไป
samvv

จริงอยู่ที่ @samvv (ทั้งหมดขึ้นอยู่กับการตั้งค่าสภาพแวดล้อม)
San Jay Falcon

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