การเปลี่ยนชื่อไฟล์ใน linux ด้วย regex


9

ฉันมีกลุ่มของไฟล์ที่ฉันต้องการเปลี่ยนชื่ออย่างต่อเนื่องไฟล์มีชื่อเหมือน

"System-Log-01-01-2009-NODATA.txt"
"Something-Log-01-01-2009-NODATA.txt"

และฉันต้องการให้พวกมันเป็นตัวพิมพ์เล็ก yyyymmdd, .log extension

"system.20090101.log"
"something.20090101.log"

คำตอบ:


14

ฉันเคยเขียนสคริปต์ Perl เพื่อทำสิ่งนี้จนกระทั่งฉันค้นพบคำสั่งเปลี่ยนชื่อ

มันยอมรับ regl Perl เพื่อทำการเปลี่ยนชื่อ:

สำหรับสิ่งนี้ฉันเพิ่งพิมพ์สองคำสั่ง:

rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *
rename 'y/A-Z/a-z/' *.log

สำหรับ distros บางส่วน แต่renameไม่ได้มีการทำงานนี้ (ดูหน้าคน) และคุณอาจจะมีการติดตั้งหรือperl-renameprename


คำตอบที่ดีมาก
Judioo

8
ระวัง distros บางตัวจะส่งคำสั่งเปลี่ยนชื่อไร้ค่า ตรวจสอบว่า distro ของคุณมีอันไหนก่อน
Derobert

ฉันรู้mmvแต่ในที่สุดก็ต้องขอบคุณrenameฉันที่สามารถใช้พลังของ regex
Ludovic Kuty

5
เมื่อวันที่ Arch Linux perl-renameนี้อยู่
Oleh Prypin

6

เนื่องจากฉันไม่มีคำสั่งเปลี่ยนชื่อฉันจึงใช้สิ่งนี้:

for myfile in /my/folder/*; do
    target=$(echo $myfile|sed -e 's/foo/bar/g')
    mv "$myfile" "$target"
done

5

mmvเป็นยูทิลิตี้ลินุกซ์มาตรฐานเพื่อย้าย / เปลี่ยนชื่อหลายไฟล์ มันสามารถใช้ได้จาก repos สำหรับการกระจายส่วนใหญ่ สำหรับตัวอย่างของคุณด้านบนคุณสามารถทำได้:

mmv *-Log-*-*-*-NODATA.txt #l1.#4#3#2.log

สำหรับข้อมูลเพิ่มเติมโปรดอ่านบทความ debadayหรือหน้าคน


5

renameutil ไม่มาก "มาตรฐาน" แต่ละ distro มาพร้อมกับrenameเครื่องมือที่แตกต่างกัน ตัวอย่างเช่นที่นี่ใน Gentoo renameมาจากsys-apps/util-linuxแพ็คเกจและไม่สนับสนุน regex

Hamish Downerแนะนำmmvดูเหมือนว่ามีประโยชน์เป็นพิเศษสำหรับใช้ในสคริปต์

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

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


ใน Gentoo คุณสามารถออกsys-apps/renameแพ็คเกจซึ่งจะให้คุณrenamexmทำการเปลี่ยนชื่อ regex รวมถึงมวลบน / ตัวพิมพ์เล็กและสิ่งดีๆอื่น ๆ
radicand

1

เพื่อความเป็นธรรม:

rename 's/(\w+)-(\w+)-(\d\d)-(\d{4})-NODATA.txt\$1.$4$3$2.log$//' *.txt

ให้ผลลัพธ์นี้:

Use of uninitialized value $4 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $3 in regexp compilation at (eval 1) line 1.
Use of uninitialized value $2 in regexp compilation at (eval 1) line 1.

แต่:

rename -n 's/(\w+)-\w+-(\d{2})-(\d{2})-(\d{4})-NODATA\.txt$/$1.$4$3$2\.log/' *.txt && rename 'y/A-Z/a-z/' System.20090101.log

ให้ผลลัพธ์ที่ถูกต้อง:

System-Log-01-01-2009-NODATA.txt renamed as System.20090101.log
System.20090101.log renamed as system.20090101.log

แทนที่ {-n} สวิตช์ด้วย {-v}


1

ฉันสร้างสคริปต์ทุบตีขนาดเล็กเพื่อทำสิ่งนี้:

#!/bin/bash

for f in `ls /path/to/folder`; do
  # Create new filename from the old one
  # This example replaces A (upper case) with a (lower case)
  new_file=`echo "$new_file" | tr A a`

  # Rename the file
  mv "$f" "$new_file"
done

โดยทั่วไปการแยกวิเคราะห์lsผลลัพธ์ไม่ใช่ความคิดที่ดีที่สุด การค้นหาแบบสุ่มดึงการอ่าน longish นี้บนUnix SEเพื่อความสนุกของคุณ | นอกจากนี้คำตอบของคุณน่าจะตรงกับคำถามกับtr '[:upper:]' '[:lower:]'
HBruijn
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.