ไฟล์เฉพาะของ Linux (mv หรือ cp) จากรายการข้อความของไฟล์?


34

ฉันมีไดเรกทอรีหลายไฟล์บางอย่างเช่นไฟล์ 50,000 ไฟล์และไฟล์อื่น ๆ บนเซิร์ฟเวอร์ ฉันต้องการย้ายไฟล์เฉพาะไปยังไดเรกทอรีอื่น ฉันสามารถสร้างรายการไฟล์ที่ต้องย้ายในรูปแบบ csv หรือรูปแบบข้อความอื่น ๆ

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

มีวิธีง่าย ๆ ในการทำเช่นนี้? ข้อเสนอแนะหรือทรัพยากรใด ๆ จะได้รับการชื่นชมอย่างมาก


นอกจากนี้ไฟล์จะถูกตั้งชื่อแบบสุ่มเมื่อมีการเพิ่มลงในไดเรกทอรี ไม่มีแบบแผนการตั้งชื่อหรือตรรกะใด ๆ ที่สามารถใช้เพื่อย้ายไฟล์เฉพาะ
Jestep

คำตอบ:


26

rsync มีหลายตัวเลือกที่สามารถนำรายชื่อของไฟล์ที่จะดำเนินการ ( --files-from, --include-fromฯลฯ )

ตัวอย่างเช่นนี้จะทำเคล็ดลับ:

rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory

2
ตัวอย่าง:rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory
anneb

28

เพื่อหลีกเลี่ยงการใช้cat(และหากคุณไม่ได้ใช้rsync):

xargs -a file_list.txt mv -t /path/to/dest

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


2
ข้อเสียอย่างหนึ่งของวิธีการนี้คือหากไฟล์ในรายการมีชื่อพา ธ (เช่นไฟล์เหล่านั้นไม่ได้อยู่ในไดเรกทอรีเดียวกัน) การใช้mvจะยุบไฟล์ทั้งหมดลงในไดเรกทอรีปลายทางเดียวกัน rsyncแนวทางในคำตอบที่ได้รับการยอมรับไม่ประสบข้อ จำกัด นี้
Jason R

นอกจากนี้ฉันได้ลองใช้คำสั่งนี้และ xargs จะแตกไฟล์ใด ๆ ที่มีเครื่องหมายคำพูดเดี่ยว ("คำพูดเดี่ยวที่ไม่มีใครเทียบ")
James Beninger

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

15
for file in `cat listoffiles`; do mv "$file" /path/of/destination ; done

สมมติว่าทุบตีบวกlistoffilesที่มีหนึ่งไฟล์ต่อบรรทัด ข้อคัดค้านเพียงอย่างเดียวของฉันในเส้นทาง rsync คือ OP ขอวิธีการย้ายไฟล์ไม่ใช่การคัดลอก rsync มีธงมากกว่างานอภิเษกดังนั้นฉันแน่ใจว่ามันสามารถแก้ไขเพิ่มเติมเพื่อทำเช่นนั้น แต่บางครั้งง่ายกว่าจะดีกว่า!


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

4
ดีฉันมีปัญหาเกี่ยวกับช่องว่างดังนั้นฉันจึงแก้ไขเป็น:while read -r file; do mv "$file" /path/of/destination ; done < listoffiles
user1182474

1
@ user1182474 ขอบคุณและการใช้การเปลี่ยนเส้นทางอินพุตอย่างสง่างาม วิธีการดั้งเดิมของการแสดงความพึงพอใจพร้อมคำตอบคือการถอนออกโดยวิธี!
MadHatter สนับสนุนโมนิก้า

1
@ user1182474 ขอบคุณสำหรับสิ่งนั้น! ขั้นตอนสุดท้ายในการปรับเปลี่ยนหลายอย่างต้องทำแบบสุ่มสี่สุ่มห้าเพื่อทำการพอร์ตอรรถประโยชน์การสำรองข้อมูล OSX ของฉันไปยัง Android ของฉัน!
Charlie Gorichanaz

4

ขึ้นอยู่กับรูปแบบของไฟล์ข้อความที่คุณมี ตัวอย่างเช่นหากคุณมีรายการไฟล์ที่เขียนเช่นนั้นแต่ละไฟล์จะอยู่ในบรรทัดใหม่ คุณสามารถใช้ xargs เช่น:

$ cat your_text_file | xargs cp -t /path/to/destination

นอกจากนี้คุณยังสามารถใช้findคำสั่งพร้อม-execตัวเลือก เพื่อคัดลอก / ย้ายไฟล์


3
rsync --files-from=file_list.txt /path/to/source/ /path/to/dest/

Rsync มีประโยชน์เพิ่มเติมมากกว่าcpหรือmvคำสั่งเพราะมันจะสร้างโฟลเดอร์โดยอัตโนมัติหากพวกเขาไม่อยู่


ทำไมจึง/path/to/sourceต้องใช้เมื่อใช้พา ธ จากรายการไฟล์
bzero

@bzero รายการไฟล์อาจมีเส้นทางสัมพันธ์
DreadfulWeather

2

ฉันคิดว่าคำตอบ rsync เป็นคำตอบที่ดีกว่า แต่สำหรับตัวเลือกอื่น:

tar -cf - -T FILE_OF_FILENAMES_TO_MOVE.txt |(cd /path/to/new/dir && tar -xvf -)

นี่เป็นสิ่งที่ดีสำหรับ Dockerfile เนื่องจาก tar มีอยู่ในอิมเมจพื้นฐานของ Ubuntu แต่ไม่ใช่ rsync
kristianp

1

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

ในการแก้ไขปัญหานี้ฉันได้ทำสิ่งต่อไปนี้:

ls -rt /path/to/cluttered/destination/directory/ > /opt/dircheck/filestomove คำสั่งดังกล่าวจะสร้างไฟล์ filestomove ที่จะเป็นรายการเนื้อหาทั้งหมดของไดเรกทอรีปลายทางย้อนกลับเรียงตามเวลาหมายถึงเก่าที่สุดถึงใหม่ที่สุด

จากนั้นฉันสร้างไดเรกทอรีย่อยของไดเรกทอรีปลายทางที่ยุ่งเหยิงในขณะนี้เพื่อย้ายข้อมูลไปไว้

mkdir /path/to/cluttered/destination/directory/newsubdirectory

จากนั้นฉันทำซ้ำรายการไดเรกทอรียกเว้นรายชื่อไปที่หน้าจอและแสดงรายละเอียดเพิ่มเติม

ls -lrht /path/to/cluttered/destination/directory/ บรรทัดนี้แสดงรายการไดเรกทอรีเรียงตามวันที่จากน้อยไปมาก (เรียงลำดับย้อนกลับตามเวลา) และแสดงข้อมูลเพิ่มเติมรวมถึงการประทับวันที่ / เวลาของแต่ละไฟล์ในไดเรกทอรีปลายทางที่รกในขณะนี้ ฉันอ้างถึงสิ่งนี้เริ่มต้นที่ด้านบนเพื่อแสดงสิ่งที่ไดเรกทอรีและไฟล์ที่ฉันต้องการให้พวกเขาอยู่ที่ไหน จะมีช่องว่างในการประทับวันที่ / เวลาของไฟล์ที่ไฟล์ใหม่ทั้งหมดเริ่มต้นซึ่งไม่ควรมี

จากนั้นฉันจะแก้ไขไฟล์ filestomove ที่สร้างขึ้นในขั้นตอนแรกข้างต้น (ซึ่งจัดเรียงตามวันที่) และลบบางส่วนออกจากรายการที่มีก่อนหน้านี้ที่ฉันต้องการอยู่จากไดเรกทอรีเดิม

vim /opt/dircheck/filestomove ลบจากด้านบนไฟล์ทั้งหมดที่คุณไม่ต้องการย้าย

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

sudo xargs -a /opt/dircheck/filestomove mv -t /path/to/cluttered/destination/directory/newsubdirectory

สิ่งนี้ย้ายไฟล์ทั้งหมดในเสี้ยววินาที (หมายเหตุ: คุณอาจไม่จำเป็นต้องใช้ sudo ในตอนแรกนี่เป็นเรื่องของการอนุญาตไฟล์)

ตอนนี้ไดเรกทอรีปลายทางดั้งเดิมของฉันนั้นดีและสะอาดและมีไดเรกทอรีใหม่ที่มีไฟล์และไดเรกทอรีทั้งหมดที่รกอยู่


1

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

cat filenames.txt | xargs mv -t /path/to/move/files/to

(โดยทั่วไปดู man xargsมันยอดเยี่ยม)

หาก mv เฉพาะของคุณไม่มีตัวเลือก -t คุณสามารถทำเล่ห์เหลี่ยมบางอย่างเช่น

( cat filenames.txt; echo; echo /path/to/move/files/to ) | xargs mv

หมายเหตุ - สิ่งเหล่านี้จะไม่ทำงานอย่างที่คาดไว้หากมีชื่อไฟล์ที่มีการขึ้นบรรทัดใหม่


อย่างไรก็ตาม; ดูคำตอบของอิกนาชิโอ rsync เรียงลำดับจากสิ่งนี้
Kjetil Joergensen

cp, mvและชอบไม่ได้มี-tตัวเลือกในBSD 's และเป็นตัวอย่างที่สองกับ subshell ไม่ทำงานสำหรับฉัน ( /path/to/moveถูกผนวกเป็นชื่อไฟล์สุดท้าย)

1
@ w17t - เสียงเหมือน filenames.txt ไม่ได้จบด้วยการขึ้นบรรทัดใหม่ไม่ว่าจะเพิ่มบรรทัดใหม่ที่ส่วนท้ายของ filenames.txt หรือทำสิ่งที่ต้องการ(cat filenames.txt; echo; echo /path/to/move/files/to) | xargs mv
Kjetil Joergensen

0

ลองสิ่งที่ชอบ:

cat list.txt | while read line; do mv "$line" /images; done

จะได้รับwhile read line; do mv $line /images; done < list.txt เป็นคำสั่งเดียว
ignivs

0

ต่อไปนี้ทำงานสำหรับฉันที่ฉันต้องการคัดลอกไฟล์ PNG ทั้งหมดจากเส้นทางเฉพาะ (และส่วนย่อยทั้งหมด) ไปยังตำแหน่งใหม่ในขณะที่รักษาโครงสร้างไดเรกทอรี:

rsync -av --prune-empty-dirs --include='*/' --include='*.png' --exclude='*' source/ destination/

เนื่องจาก RSYNC สร้างมิเรอร์ของโครงสร้างไดเรกทอรีก่อนจากนั้นจึงซิงค์ไฟล์คุณจึงสามารถจบด้วยโฟลเดอร์ส่วนเกินที่ว่างเปล่า ฉันใช้แฟล็ก --prune-empty-dirs เพื่อลบไดเร็กทอรีว่างเหล่านี้

ฉันไม่มีส่วนเกี่ยวข้อง แต่คิดว่าถูกต้องที่จะให้เครดิตกับแหล่งที่เป็นแรงบันดาลใจให้กับโซลูชันนี้: http://techblog.zabuchy.net/2011/transfer-only-selected-file-types-with-rsync/

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