มวลเปลี่ยนส่วนของชื่อไฟล์หรือไม่?


4

ฉันมีไฟล์ทั้งกลุ่มชื่อดังต่อไปนี้ (ตัวอย่าง):

ADVANTE  18''8.0 PCD5'114.3 ET45 CB73.1.jpg
ADVANTE  18x8.0 PCD6139.7 ET20 CB110.2.jpg
ADVANTE 'A MI576B 20''8.5 PCD6'139.7 ET25 CB110.2 GBXZLDCP.jpg
ADVANTE 'A SH10 15''6.5 PCD8'100-114.3 ET40 CB73.1 3FPBU.jpg

ฉันจะไปที่แต่ละไฟล์และเปลี่ยนชื่อไฟล์บางส่วนเป็น:

ADVANTI  18''8.0 PCD5'114.3 ET45 CB73.1.jpg
ADVANTI  18x8.0 PCD6139.7 ET20 CB110.2.jpg
ADVANTI 'A MI576B 20''8.5 PCD6'139.7 ET25 CB110.2 GBXZLDCP.jpg
ADVANTI 'A SH10 15''6.5 PCD8'100-114.3 ET40 CB73.1 3FPBU.jpg

ใช้คำสั่งหรือแอพบางประเภท? ใช้เวลานานเกินไปในการเปลี่ยนชื่อแต่ละรายการด้วยตนเอง

คำตอบ:


5

หากคุณใช้เปลือก ZSH สิ่งนี้สามารถทำได้อย่างง่ายดายใน Terminal ด้วย zmv (ราคารวม ด้วย OS X โดยค่าเริ่มต้น). ทำไมต้องใช้สคริปต์แฟนซีหากงานเสร็จแล้ว

ชนิด zsh ในหน้าต่างเทอร์มินัลหากด้วยเหตุผลบางอย่างที่ทำให้คุณไม่ได้ตั้งค่าให้เป็นเชลล์เริ่มต้น

autoload zmv
zmv 'ADVANTE(*)' 'ADVANTI$1'

ตอนนี้เป็นเกรด A เหตุผลที่ยอดเยี่ยมที่จะยิง zsh :) +1
bmike

มันบอกว่า localhost% zmv 'ADVANTE(*)' 'ADVANTI$1' zsh: command not found: zmv
Propeller

@Propeller ขออภัยสำหรับการตอบกลับล่าช้าพลาดครั้งแรก ข้อผิดพลาดหมายความว่าคุณพลาดบรรทัดแรก ( autoload zmv ) หรือคุณไม่ได้ใช้การติดตั้ง zsh ในสต็อค
ghoppe

1

ในกรณีที่คุณต้องทำสิ่งนี้บ่อยครั้ง (และด้วยรูปแบบไฟล์อื่น) สคริปต์ perl นี้ อาจพิสูจน์มีประโยชน์มาก เก็บสคริปต์ต่อไปนี้เป็นไฟล์ข้อความที่เรียกว่า rename ในสถานที่ที่สะดวก:

#!/usr/bin/perl -w
# rename - Larry's filename fixer
$op = shift or die "Usage: rename expr [files]\n";
chomp(@ARGV = <STDIN>) unless @ARGV;
for (@ARGV) {
    $was = $_;
    eval $op;
    die $@ if $@;
    rename($was,$_) unless $was eq $_;
}

จากนั้นคุณสามารถใช้นิพจน์มาตรฐาน perl ทั้งหมดเพื่อเปลี่ยนชื่อไฟล์ในกรณีของคุณ

rename 's/^ADVANTE/ADVANTI/' ADVANTE*

1
ตรวจสอบให้แน่ใจว่า "สถานที่ที่สะดวก" เป็นของคุณในปัจจุบัน $PATHและหลังจากบันทึกคุณควร chmod 755 rename เพื่อให้สามารถเรียกใช้งานได้
MattDMo

ใช่แล้วนั่นจะช่วยได้อย่างแน่นอน :-)
nohillside

1

คุณสามารถลองใช้แอพเชิงพาณิชย์ การเปลี่ยนชื่อ Finder ที่ดีขึ้น ถ้าคุณต้องการหลีกเลี่ยง Terminal พวกเขายังได้ทดลองใช้ฟรี

[คำเตือน: ไม่มีผลประโยชน์ทางการเงินใน บริษัท ที่ขาย ABFR - เป็นลูกค้าที่มีความสุข]


1

ตั้งแต่ OS X 10.10 (โยเซมิตี) คุณสามารถ ใช้ Finder เพื่อค้นหาและแทนที่สตริงในชื่อไฟล์ เลือกไฟล์ที่คุณต้องการเปลี่ยนชื่อจากนั้นเรียกใช้ Rename… ตัวเลือก คุณควรเห็นแผ่นโต้ตอบด้วย Find: และ Replace with: สาขา


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

0

คุณสามารถใช้เทอร์มินัลดังนี้:

find . -type f -maxdepth 1 -print0 | while read -d $'\0' file; do mv "$file" "$( echo "$file" | sed "s/\.\/ADVANTE/ADVANTI/" )" ; done
  • find จะใช้เพื่อแสดงรายการไฟล์ทั้งหมดที่จะเปลี่ยนชื่อ
    • . เป็นไดเรกทอรีที่จะเริ่มการค้นหา
    • -type f ระบุว่าต้องพิจารณาไฟล์เท่านั้น
    • -maxdepth 1 ระบุว่าการค้นหาไม่ควรเรียกเก็บเงินจากไดเรกทอรีย่อย
    • -print0 พิมพ์ชื่อไฟล์ตามด้วยอักขระ ASCII NUL (เนื่องจากชื่อไฟล์ของคุณมีช่องว่างเราจำเป็นต้องใช้อักขระพิเศษเพื่อแยกพวกเขา: พื้นที่ไม่สามารถใช้)
  • while read -d $'\0' file ประมวลผลชื่อไฟล์ที่ผลิตและเก็บไว้ใน $file ตัวแปร
  • echo "$file" | sed "s/\.\/ADVANTE/ADVANTI/" ทำการทดแทน (ADVANTE กับ ADVANTI)
  • mv ย้ายไฟล์แรก (ชื่อเดิม) ไปยังไฟล์ที่สอง (ไฟล์ที่มีการแทนที่)

ทดสอบกับ:

$ ls -l
total 0
-rw-r--r--  1 corti  corti  0 Feb 27 10:26 ADVANTE  18''8.0 PCD5'114.3 ET45 CB73.1.jpg
-rw-r--r--  1 corti  corti  0 Feb 27 10:26 ADVANTE  18x8.0 PCD6139.7 ET20 CB110.2.jpg
-rw-r--r--  1 corti  corti  0 Feb 27 10:26 ADVANTE 'A MI576B 20''8.5 PCD6'139.7 ET25 CB110.2 GBXZLDCP.jpg
-rw-r--r--  1 corti  corti  0 Feb 27 10:27 ADVANTE 'A SH10 15''6.5 PCD8'100-114.3 ET40 CB73.1 3FPBU.jpg
$ find . -type f -maxdepth 1 -print0 | while read -d $'\0' file; do mv "$file" "$( echo "$file" | sed "s/\.\/ADVANTE/ADVANTI/" )" ; done
$ ls -l
total 0
-rw-r--r--  1 corti  corti  0 Feb 27 10:26 ADVANTI  18''8.0 PCD5'114.3 ET45 CB73.1.jpg
-rw-r--r--  1 corti  corti  0 Feb 27 10:26 ADVANTI  18x8.0 PCD6139.7 ET20 CB110.2.jpg
-rw-r--r--  1 corti  corti  0 Feb 27 10:26 ADVANTI 'A MI576B 20''8.5 PCD6'139.7 ET25 CB110.2 GBXZLDCP.jpg
-rw-r--r--  1 corti  corti  0 Feb 27 10:27 ADVANTI 'A SH10 15''6.5 PCD8'100-114.3 ET40 CB73.1 3FPBU.jpg

2
มีเหตุผลเฉพาะที่คุณใช้หรือไม่ find -maxdepth 1 แทนที่จะเป็น for f in * ห่วง?
nohillside

2
ใช่เพราะช่องว่าง: * จะขยายในรายการโทเค็นและเชลล์จะแยกพวกมันออกจากช่องว่าง เนื่องจากรายการไฟล์มีช่องว่างเชลล์จะไม่สามารถแยกความแตกต่างได้ถ้าพื้นที่นั้นเป็นส่วนหนึ่งของชื่อหรือตัวคั่น
Matteo

1
ไม่ลองเลย touch "foo bar" foo; for i in f*; do echo $i; done
nohillside

@patrix ฉันเห็น แต่ฉันไม่เข้าใจว่าทำไม: man page บอกว่า "รายการคำต่อไปนี้ขยาย" * ในกรณีนี้ควรขยายเป็น "foo foo bar" (ดู echo * | od -abc ) * ขยายตัวแตกต่างกันหรือไม่
Matteo

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