วิธีคัดลอกไฟล์ไปยังหลาย ๆ โฟลเดอร์โดยใช้บรรทัดคำสั่ง?


67

ฉันพยายามคัดลอกไฟล์test.txtไปยังหลายไดเรกทอรีด้วยคำสั่งเดียว:

cp ~/test.txt ~/folder1 ~/folder2

แต่ฉันไม่ประสบความสำเร็จ มีวิธีทำในคำสั่งเดียวเพื่อให้ฉันสามารถคัดลอกไฟล์หรือแม้แต่โฟลเดอร์ไปยังหลายไดเรกทอรี?


ไม่สะดวก คุณอาจต้องการตรวจสอบเป็น "rsync" เพื่อการอัปเดตโฟลเดอร์ที่มีอยู่หลายชุดอย่างมีประสิทธิภาพ
Thorbjørn Ravn Andersen

3
ลองเรียนรู้ bash-script สักหน่อย มันจะมีประโยชน์มาก:for dest in folder1 folder2; do cp ~/test.txt ~/"$dest"; done
Shahbaz

ไม่ได้เป็นคำสั่งเดียว แต่ก็อาจจะช่วยให้คนบางคนที่สะดุดเมื่อที่นี่:cp ~/test.txt ~/folder1 && cp ~/test.txt ~/folder2
มนูJärvinen

ซ้ำของstackoverflow.com/a/195972/2097284
Camille Goudeseune

คำตอบ:


71

cpสามารถคัดลอกจากหลายแหล่งได้ แต่ไม่สามารถคัดลอกไปยังหลาย ๆ ปลายทางได้ ดูman cpข้อมูลเพิ่มเติม

คำสั่ง bash เดียวที่ฉันรู้ซึ่งสามารถคัดลอก / บันทึกไปยังหลาย ๆ ปลายทางteeได้

คุณสามารถใช้มันในกรณีของคุณดังนี้:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt

โปรดทราบว่าteeยังเขียนอินพุตไปยังเอาต์พุตมาตรฐาน (stdout) ดังนั้นหากคุณไม่ต้องการสิ่งนี้คุณสามารถป้องกันได้โดยเปลี่ยนเส้นทางเอาต์พุตมาตรฐาน/dev/nullเป็นดังนี้:

tee ~/folder1/test.txt ~/folder2/test.txt < ~/test.txt >/dev/null

10
ฉลาดนั่นคือการโกง! :)
terdon

5
+1 ฉลาด! และถ้าคุณใช้>/dev/nullงานกับไฟล์ไบนารีเกินไปโดยไม่ต้อง messing up ขั้ว ...
Rmano

1
+1 สำหรับคุณคุณเป็นคนเสมอ :) แต่ถ้าฉันต้องการคัดลอกไดเรกทอรี
nux

2
@nux อย่าลืมใช้-rตัวเลือกcpในกรณีของไดเรกทอรี
Radu Rădeanu

4
@nux: teeไม่เหมือนกับการcpคัดลอกเนื้อหาไฟล์เท่านั้นโดยไม่สนใจโหมดความเป็นเจ้าของการประทับเวลา เพื่อหลีกเลี่ยงการซ้ำชื่อไฟล์:f=text.txt; <~/$f tee ~/folder1/$f > ~/folder2/$f
jfs

61

อีกวิธีหนึ่งในการบรรลุการคัดลอกไปยังหลาย ๆ ตำแหน่งคือคำสั่งต่อไปนี้:

find dir1 dir2 -exec cp file.txt {} \;

หาก dir1 หรือ dir2 มีไดเรกทอรีย่อยที่คุณไม่ต้องการให้คัดลอกไฟล์ลงไปให้เพิ่ม -maxdepth 0ตัวเลือก:

find dir1 dir2 -maxdepth 0 -exec cp file.txt {} \;

โปรดทราบว่าสิ่งนี้จะเขียนทับทุกไฟล์ในdir1และdir2ด้วยfile.txtเนื้อหาของนอกเหนือจากการคัดลอก หากต้องการคัดลอกfile.txtโดยไม่ส่งผลกระทบต่อไฟล์อื่นในไดเรกทอรีเหล่านี้ให้บอกfindให้ดำเนินการกับไดเรกทอรีเท่านั้น:

find dir1 dir2 -type d -exec cp file.txt {} \;

4
ทางออกที่ดี! ดูเหมือนว่าฉันจะสมบูรณ์แบบมากกว่าที
Danatela

1
แน่นอนว่าไม่มีการเปลี่ยนเส้นทางที่เกี่ยวข้องและยังคงเป็นคำสั่งเดียว
Sylvain Pineau

2
@SylvainPineau ในความเป็นจริงมี 3: หนึ่งfindและสองครั้ง cp(ในกรณีนี้) ไม่ต้องบอกว่าfindต้องใช้เวลาเยอะ
Radu Rădeanu

3
หากคำจำกัดความของคำสั่ง "" เป็นการเรียก "exec" อาจเป็นไปได้ แต่นี่คือ "หนึ่งคำสั่ง" ในหนังสือของฉัน
kojiro

2
ฉันกลับมาที่นี่ต่อไปดังนั้นคิดว่าฉันควรให้ upvote: D
Jonathan

31

คำสั่ง

cp ~/test.txt ~/folder1 ~/folder2

พยายามที่จะคัดลอกแฟ้มที่สอง ( ~/test.txtและ ~/folder1) folder2ไปยังปลายทาง (และถ้า~/folder2มีอยู่และเป็นไดเรกทอรีคุณจะได้รับคำเตือน "ไดเรกทอรีที่ไม่ใช้")

หากคุณต้องการทำสำเนาหลายไฟล์test.txtคุณต้องใช้การวนซ้ำหรือหลายคำสั่ง ...

for i in ~/folder1 ~/folder2; do cp  ~/test.txt $i; done 

(... และโปรดระวังหากคุณมีช่องว่างฝังอยู่ในชื่อไฟล์คุณจะต้องมีข้อความ)

ในการคัดลอกไดเรกทอรีทั้งหมดคุณต้องใช้-rตัวเลือก:

for i in ~/folder1 ~/folder2; do cp -r ~/folder3 $i; done

สิ่งนี้จะสร้าง~/folder1/folder3และ~/folder2/folder3มีไฟล์ทั้งหมดรวมอยู่ด้วย


1
สำหรับผู้อ่านที่ผ่าน: ตามspec , สำหรับห่วงเป็นคำสั่งผสม ดังนั้นนี้จะยังคงเป็นหนึ่งในคำสั่งและตรงตามความต้องการทั้งหมดสำหรับคำถามที่ว่า
kojiro

@nux ฉันไม่เห็นด้วยกับการแก้ไข 1) ทั้งสองพิมพ์ผิดฉันตั้งใจจะแทรกคำสั่งลงในวลี 2) จุดไข่ปลาเป็นเรื่องของสไตล์; โปรดให้สไตล์ของฉันด้วย
Rmano

1
โอเคฉันขอโทษชายฉันคิดว่ามันจะดูดีขึ้น
nux

ในระบบของฉันมันไม่บันทึก folder3 เป็น ~ / folder1 / folder3 แต่คัดลอกทุกอย่างใน folder3 ลงใน folder1
alpha_989

23

คุณสามารถสร้างสคริปต์ช่วยเหลือหรือคุณสามารถทำได้ด้วยxargsและฟังก์ชั่นการพิมพ์ (ในกรณีนี้echo):

echo firstDir secondDir | xargs -n 1 cp test

สิ่งนี้จะทำให้แต่ละไดเรกทอรีเป็นอาร์กิวเมนต์ของcpฟังก์ชันโดยใช้ไฟล์ทดสอบเป็นพารามิเตอร์


นี่อาจเป็นคำตอบที่ดีที่สุด / ตรงที่สุดสำหรับคำถาม
Bryson S.

7

หลังจากค้นหามานานแล้วงานนี้ก็มีเสน่ห์เช่นกัน!

for dir in *; do [ -d "$dir" ] && cp /path/file.txt "$dir" ; done

สิ่งนี้จะคัดลอกfile.txtไปยังทุกไดเรกทอรีในตำแหน่งปัจจุบันของคุณในเทอร์มินัล

for dir in *; do [ -d "$dir" ] && cp -rf /path/folder "$dir" ; done

จะเป็นการคัดลอกโฟลเดอร์ไปยังทุกไดเรกทอรีย่อยในตำแหน่งปัจจุบันของคุณในเทอร์มินัล

ฉันแบ่งปันมันหวังว่าจะช่วยคนอื่นด้วย


ในzshคุณสามารถใช้for i in *(/); ...วนรอบไดเรกทอรีย่อยทั้งหมดเพื่อให้คุณสามารถหลีกเลี่ยงการ[ -d ...ทดสอบ การขยายที่ต่อเนื่องเป็นหนึ่งในเหตุผลที่ฉันชอบมากกว่าbashนี้
Rmano

รหัสของคุณสามารถถูกต้องอีกครั้งในคำสั่ง
nux

1
ในคำสั่งแรกของคำตอบนี้ได้ง่ายเป็นzsh for dir in *(/); do cp /path/file.txt "$dir"; doneดูzsh.sourceforge.net/Intro/intro_2.html
Rmano

5
คุณสามารถกำจัดการทดสอบในเชลล์ที่ได้จากบอร์นด้วยfor dir in */;
Henk Langeveld

@nux มันใช้งานได้ดีจริงๆและคำสั่งนั้นง่ายต่อการติดตาม มันควรจะถูกโหวตให้สูงขึ้นมาก!
nukeguy

1

หากคุณต้องการคัดลอกไฟล์ test.txt ในทุกไดเรกทอรีใน / tmp / target / ...

สร้างสภาพแวดล้อมการทดสอบ:

mkdir /tmp/target
cd /tmp/target
mkdir -v {folder1,folder2,folder3}
touch test.txt

คัดลอก:

find * -maxdepth 0 -type d -exec cp -vi test.txt {} \;

0

แค่คิดว่าจะให้การเปลี่ยนแปลงกับคำตอบของ Sylvain Pineau

ที่ไหนdir1และdir2ไม่ได้อยู่ในไดเรกทอรีปัจจุบันของคุณ

find ./ -maxdepth 2 -type d -name dir1 -exec cp file.txt {} \;

ค้นหาที่นี่จะมองหาdir1สองระดับลึกหรือคุณสามารถออกจาก-maxdepthพารามิเตอร์เพื่อค้นหาdir1ในโฟลเดอร์ทั้งหมดในไดเรกทอรีปัจจุบันและด้านล่าง

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