วิธีคัดลอกทุกไฟล์ที่ 4 ในโฟลเดอร์


15

00802_Bla_Aquarium_XXXXX.jpgฉันมีจำนวนมากของไฟล์ในโฟลเดอร์ที่ชื่อเหมือน ตอนนี้ผมต้องคัดลอกทุก4selected/ไฟล์ไปยังโฟลเดอร์ย่อยพูดใน

00802_Bla_Aquarium_00020.jpg <= this one
00802_Bla_Aquarium_00021.jpg
00802_Bla_Aquarium_00022.jpg
00802_Bla_Aquarium_00023.jpg
00802_Bla_Aquarium_00024.jpg <= this one
00802_Bla_Aquarium_00025.jpg
00802_Bla_Aquarium_00026.jpg
00802_Bla_Aquarium_00027.jpg
00802_Bla_Aquarium_00028.jpg <= this one
00802_Bla_Aquarium_00029.jpg

ฉันจะทำสิ่งนี้ได้อย่างไร


คุณอาจจะสามารถที่จะทำเช่นโซลูชั่นเพื่อsuperuser.com/q/396536/87552lsในการส่งออกของบางส่วน ดูstackoverflow.com/q/4553751/789593ซึ่งถามเกี่ยวกับทุกบรรทัดที่สอง
NN

หากพวกเขามีหมายเลขและคุณรู้ว่าหมายเลขสุดท้ายคุณอาจพิจารณารูปแบบของfor n in $(seq -w 20 4 200); do cp "00802_..._00${n}" ...; done
Ulrich Schwarz

คำตอบ:


12

ด้วย zsh คุณสามารถทำได้:

n=0; cp 00802_Bla_Aquarium_?????.jpg(^e:'((n++%4))':) /some/place

POSIXly ความคิดเดียวกัน verbose อีกเล็กน้อย:

# put the file list in the positional parameters ($1, $2...).
# the files are sorted in alphanumeric order by the shell globbing
set -- 00802_Bla_Aquarium_?????.jpg

n=0
# loop through the files, increasing a counter at each iteration.
for i do
  # every 4th iteration, append the current file to the end of the list
  [ "$(($n % 4))" -eq 0 ] && set -- "$@" "$i"

  # and pop the current file from the head of the list
  shift
  n=$(($n + 1))
done

# now "$@" contains the files that have been appended.
cp -- "$@" /some/place

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

cp $(printf '%s\n' 00802_Bla_Aquarium_?????.jpg | awk 'NR%4 == 1') /some/place

คุณช่วยแสดงความคิดเห็นด้วยรหัส posix ได้หรือไม่
Rahul Patil

@ChrisDown for i doเป็นมาตรฐานและพกพาได้ง่ายกว่าfor i; doและเป็นวิธีมาตรฐานในการวนรอบพารามิเตอร์ตำแหน่ง
Stéphane Chazelas

7

ในทุบตีเป็นไปได้ตลกที่จะทำงานค่อนข้างดีที่นี่:

cp 00802_Bla_Aquarium_*{00..99..4}.jpg selected

นั่นเป็นคำตอบที่สั้นและมีประสิทธิภาพมากที่สุดแน่นอน: ไม่มีการแบ่งย่อย, ไม่มีการวน, ไม่มีท่อ, ไม่มีawkกระบวนการภายนอกวอร์ด เพียงแค่หนึ่งส้อมcp(ซึ่งคุณไม่สามารถหลีกเลี่ยงได้) และหนึ่ง bash brace expansion และ glob (ที่คุณสามารถกำจัดได้ทั้งหมดเนื่องจากคุณรู้ว่ามีไฟล์กี่ไฟล์)


4
…และ 2 ข้อสมมติฐาน: ไฟล์จะถูกกำหนดหมายเลขอย่างต่อเนื่องและอันแรกหารด้วย 4.
จัดการ

@manatwork ไม่มีปัญหาถ้าคนแรกไม่หารด้วย 4: เช่นถ้าคุณต้องการcp 00802_Bla_Aquarium_*{03..99..4}.jpg selected 3 mod 4(ฉันใช้ความจริงที่ยอดเยี่ยมที่ 100 หารด้วย 4) ตอนนี้เกี่ยวกับไฟล์ที่มีหมายเลขอย่างต่อเนื่องคำตอบอื่น ๆ ทั้งหมดถือว่าเหมือนกัน
gniourf_gniourf

คำตอบอื่นใดที่มีการนับเลขอย่างต่อเนื่อง ฉันพบเฉพาะความคิดเห็นของ Ulrich Schwarzและไม่มีคำตอบเช่นนั้น
จัดการ

5

ง่ายๆด้วยการทุบตีคุณสามารถทำ:

n=0
for file in ./*.jpg; do
   test $n -eq 0 && cp "$file" selected/
   n=$((n+1))
   n=$((n%4))
done

รูปแบบ./*.jpgจะถูกแทนที่ด้วยรายการชื่อไฟล์ที่เรียงลำดับตามตัวอักษรตามที่ระบุโดย bash man ดังนั้นควรสอดคล้องกับวัตถุประสงค์ของคุณ


ในทุบตีสามบรรทัดของคุณภายในห่วงสามารถถูกแทนที่ด้วยเพียงบรรทัดนี้for . แต่ปัญหาคือว่าคุณกำลัง forking สำหรับแต่ละไฟล์ที่ไม่ได้มีประสิทธิภาพจริงๆ (((++n)%4)) || cp "$file" selected/;-)cp
gniourf_gniourf

1

หากคุณrubyติดตั้งแล้วคุณสามารถใช้หนึ่งซับต่อไปนี้ โปรดทราบว่ามันถือว่าไดเรกทอรีที่เลือกมีอยู่

ruby -rfileutils -e 'files = Dir.glob("*.jpg").each_slice(4) { |file| FileUtils.cp(file.first, "selected/" + file.first) }'

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


1

หากคุณรู้ว่าคุณจะไม่มีบรรทัดใหม่ในชื่อไฟล์คุณสามารถใช้:

find . -maxdepth 1 -name "*.jpg" | sort | while IFS= read -r file; do
  cp "$file" selected/
  IFS= read -r; IFS= read -r; IFS= read -r
done

@Gilles: ขอบคุณสำหรับการแก้ไข ฉันลบตัวแปรไฟล์ในการอ่าน 3 ทั้งๆที่ฉันต้องการชี้ให้เห็นว่าพวกเขาไม่จำเป็น
jfg956

1

คุณสามารถใช้ตัวจัดการไฟล์ GUI และปรับขนาดเส้นขอบของหน้าต่างจนกว่าไฟล์ทุก 5 ไฟล์จะครอบครองแถวจากนั้นใช้เมาส์เพื่อเลือกคอลัมน์แรก ...


-1

เมื่อดูที่ stackoverflow.com/q/4553751/789593 ซึ่งเสนอวิธีการคัดลอกหนึ่งวินาทีตามที่ @NN กล่าวถึงวิธีแก้ปัญหาที่ง่ายมากคือ:

  • ลบไฟล์แรกจากโฟลเดอร์เริ่มต้น
  • คัดลอกทุกวินาทีจากโฟลเดอร์เริ่มต้นไปยังโฟลเดอร์กลาง
  • คัดลอกทุกวินาทีหนึ่งจากโฟลเดอร์กลางลงในโฟลเดอร์สุดท้าย
  • เพิ่มไฟล์แรกด้วยตนเอง

อาจไม่มีประสิทธิภาพมากเนื่องจากต้องมีขั้นตอนการคัดลอกเพิ่มเติมเล็กน้อยซึ่งควรทำง่ายมาก

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