วิธีการเปลี่ยนชื่อหลายไฟล์ในไดเรกทอรีในเวลาเดียวกัน


12

ฉันมีไดเรกทอรีบอกว่า/var/tmp/abcมี 4 ไฟล์:

12345-ram-3e3r5-io9490-89adu9.csv
45434-dam-qwe35-to9490-43adu9.csv
11234-cam-yy3r5-ro9490-85adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv

ฉันต้องการเปลี่ยนชื่อไฟล์ CSV ทั้งหมด (ค้นหาไฟล์ทั้งหมด & เปลี่ยนชื่อไฟล์) ในวิธีที่สั้นที่สุด (อาจเป็นหนึ่งซับ) วิธีนี้:

XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

คำตอบ:


15

rename -n 's/(\w+)/XXXXX/' *.csv

ลบ-nเมื่อมีความสุข


2
renameสำหรับรุ่นที่เหมาะสม ฉันถือว่านี่คือ Larry Wall's renameจาก renameแพ็คเกจใน Debian และอนุพันธ์ (และ IIRC prenameในระบบของ RedHat persuasion) เครื่องมือที่มีประโยชน์มาก
xenoid

2
perl-renameใน linux arch
lesmana

1
@Shawarden ฉันพยายามรันคำสั่งและอ่านส่วนที่เกี่ยวข้องของ man page เพื่อทำความเข้าใจกับรูปแบบการแทนที่ แต่เมื่อทำการเพิ่มverboseflag มันจะไม่แสดงผลใด ๆ และไม่ทำการเปลี่ยนแปลงชื่อไฟล์แม้ว่าเส้นทางปัจจุบันจะมี 12345_foo.csvไฟล์ที่มีชื่อคล้ายกับ ฉันต้องทำงานเพิ่มเติมหรือไม่เพื่อให้มันทำงานได้ (ในปัจจุบันบน Fedora 30)? มันเป็นวิธีที่สะอาดกว่าการวนซ้ำ ขอบคุณล่วงหน้า!
danieldeveloper001

3
@ danieldeveloper001 คุณใช้renameหรือprenameไม่ ดูความคิดเห็นของฉันด้านบน man {the command}รายชื่อผู้เขียนในตอนท้าย
xenoid

2
สิ่งนี้ใช้ได้กับระบบที่ได้จาก Debian เท่านั้น ระบบที่ได้มาจาก Fedora มีrenameคำสั่งที่แตกต่างอย่างสิ้นเชิง ดูunix.stackexchange.com/a/238862/135943
Wildcard

11

ลอง:

for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done

มันทำงานอย่างไร:

  • for f in *.csv; do

    นี่เป็นการวนซ้ำ*.csvไฟล์ทั้งหมด

  • mv -i -- "$f" "XXXXX-${f#*-}"

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

  • done

    นี่เป็นจุดสิ้นสุดของลูป

ตัวอย่าง:

$ ls -1
11234-cam-yy3r5-ro9490-85adu9.csv
12345-ram-3e3r5-io9490-89adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv
45434-dam-qwe35-to9490-43adu9.csv
$ for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done
$ ls -1
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

4

ฉันชอบความท้าทายเล็กน้อยที่คุณโพสต์ดังนั้นนี่คือทางออกของฉัน ฉันสมมติว่าไฟล์ทั้งหมดของคุณเริ่มต้นด้วยตัวเลข 5 ตัวดังนั้นใช้คำสั่ง cutเพื่อแทนที่ไฟล์ตัวเลขเริ่มต้นด้วย "XXXXX"

ด้านล่างนี้เป็นไฟล์ก่อนคำสั่ง

-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 11111_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 12345_baz_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml

ด้านล่างคำสั่งซับเดียว

for src in *.csv; do dst=XXXXX$(echo $src| cut -c6-); mv $src $dst; done;

ด้านล่างไฟล์หลังจากคำสั่ง

-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 XXXXX_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 XXXXX_baz_file.csv

นั่นคือสิ่งที่คุณกำลังมองหา? :)

อ้างอิง:

วนรอบคำสั่งเอาต์พุตเป็น bash

สตริงในทุบตี


2
Bash สามารถจัดการสตริงประเภทนี้ได้โดยไม่ต้องแยกกระบวนการใหม่สำหรับแต่ละรายการโปรดคำตอบอื่น ๆเกี่ยวกับวิธีการ
chx

1
@chx เห็นคำตอบอื่น ๆ อยู่แล้วและได้รับความรู้เล็กน้อยจากมัน แต่ขอบคุณที่ชี้ให้พวกเขาเห็น คุณช่วยอธิบายรายละเอียดได้no need to fork a new process for eachไหม?
danieldeveloper001

3
cutเป็นไบนารีแยกต่างหาก ( /usr/bin/cut) และการรันมันใช้ทรัพยากรมากกว่าการใช้เชลล์บิวด์อิน
chx

2
ฉันเห็นว่ามันสำคัญจริง ๆ ถ้าเจตนาจะเปลี่ยนชื่อไฟล์จำนวนมาก ขอบคุณสำหรับการชี้แจง!
danieldeveloper001

1

ไม่มีส้อม:

ls | perl -lne '$suf=substr($_,6); rename $_, "XXXXX-$suf"'

เมื่อคุณใช้ shell loop mvไฟล์นั้นจะทำการหนึ่งครั้งต่อไฟล์ renameคำสั่งของ Perl ไม่ได้

(คำสั่งเปลี่ยนชื่อของ Perl มีข้อ จำกัด บางประการ แต่ในกรณีนี้ข้อ จำกัด เหล่านั้นไม่ได้นำมาใช้)

สำหรับrenameคำสั่งที่แสดงไว้ก่อนหน้านี้ใช่ว่าใช้งานได้ แต่คุณมีความสับสนระหว่างการเปลี่ยนชื่อสองประเภทและอื่น ๆ หากคุณมีสิ่งที่ถูกต้องยอดเยี่ยม แต่ถ้าไม่มีก็ใช้ได้เช่นกัน

หากคุณไม่มีคำสั่ง perl-rename และไม่สามารถติดตั้งได้คุณสามารถทำได้ดังนี้:

ls | perl -lne '$old=$_; s/(\w+)/XXXXX/; rename $old, $_'

อย่างที่คุณเห็นสิ่งนี้ใช้การแทนที่แบบเดียวกับที่แสดงในคำตอบยอดนิยม แน่นอน Perl เปลี่ยนชื่อมีระฆังและ whistles อื่น ๆ (คำตอบด้านบนที่กล่าวถึง-nแล้วแล้วมี-0, -fและอื่น ๆ ) และอื่น ๆ อีกมากมายของพวกเขาที่คุณต้องการที่มากกว่าที่คุณควรติดตั้งที่แทนการกลิ้งของคุณเองในลักษณะนี้ .


การใช้งานปกติของไปป์จะมี forks
muru

ฉันหมายถึง "จะไม่แยกไฟล์หนึ่งครั้งเพื่อเปลี่ยนชื่อ" ซึ่งแตกต่างจากแม้กระทั่งเชลล์ซึ่ง "mv" ใช้ส้อม / usr / bin / mv หรืออะไรก็ตาม นี่เป็นเพราะคำสั่ง "rename" เป็นคำสั่งภายในของ perl ที่เรียกการเปลี่ยนชื่อ () ใน libc โดยตรง แน่นอนมันมีข้อ จำกัด บางอย่าง แต่ในตัวอย่างนี้ข้อ จำกัด เหล่านั้นไม่ได้ใช้
sitaram

1
นั่นเป็นความจริงของrenameคำสั่ง ( คำตอบยอดนิยมใช้ Perl) ดังนั้นบางทีคุณควรเพิ่มคำอธิบายเล็ก ๆ น้อย ๆ มากกว่าเพียงแค่ "no forks" ในคำตอบ
muru
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.