เปลี่ยนชื่อหลายไฟล์ตามรูปแบบใน Unix


249

มีหลายไฟล์ในไดเรกทอรีที่ขึ้นต้นด้วยคำนำหน้า fghตัวอย่างเช่น:

fghfilea
fghfileb
fghfilec

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


1
ตรวจสอบที่นี่: theunixshell.blogspot.com/2013/01/30
วีเจย์

คำถามที่เกี่ยวข้อง: วิธีที่ดีกว่าที่จะเปลี่ยนชื่อไฟล์ขึ้นอยู่กับรูปแบบหลาย
Michael Le Barbier Grünewald

คำตอบ:


290

มีหลายวิธี แต่ใช้ renameอาจจะง่ายที่สุด

ใช้หนึ่งเวอร์ชันrename:

rename 's/^fgh/jkl/' fgh*

ใช้รุ่นอื่นrename(เช่นเดียวกับคำตอบของ Judy2K ):

rename fgh jkl fgh*

คุณควรตรวจสอบหน้าคนของแพลตฟอร์มของคุณเพื่อดูว่าข้อใดข้างต้นที่ใช้


7
+1 ไม่รู้ด้วยซ้ำเกี่ยวกับการเปลี่ยนชื่อ ... ตอนนี้ฉันสามารถหยุดการใช้ลูปสำหรับ mv และ sed ... ขอบคุณ!
balpha

2
คุณมีการเชื่อมโยงที่แตกต่างกันrenameแล้วคุณจะแสดงไวยากรณ์สำหรับunixhelp.ed.ac.uk/CGI/man-cgi?renameเป็นอีกคนหนึ่ง
Hasturkun

7
ไม่ปรากฏในระบบ * nix ทั้งหมด ไม่ได้อยู่ใน Max OS X สำหรับหนึ่งและไม่มีแพ็คเกจที่จะได้รับ ยังไม่ได้ดู MacPorts
dmckee --- ผู้ดูแลอดีตลูกแมว

6
AFAICT renameดูเหมือนว่าจะเป็นสคริปต์หรือยูทิลิตีเฉพาะของ Linux หากคุณสนใจเกี่ยวกับการพกพาโปรดใช้งานต่อไปsedและใช้ลูปหรือสคริปต์ Perl แบบอินไลน์
D.Shawley

33
brew install renameบน OS X :)
sam

117

นี่คือวิธีsedและmvสามารถใช้ร่วมกันเพื่อทำการเปลี่ยนชื่อ:

for f in fgh*; do mv "$f" $(echo "$f" | sed 's/^fgh/jkl/g'); done

ตามความคิดเห็นด้านล่างหากชื่อไฟล์มีช่องว่างเครื่องหมายอัญประกาศอาจต้องล้อมรอบฟังก์ชันย่อยที่ส่งคืนชื่อเพื่อย้ายไฟล์ไปที่:

for f in fgh*; do mv "$f" "$(echo $f | sed 's/^fgh/jkl/g')"; done

1
ใกล้มาก. โปรดทราบว่าคุณต้องการให้ตรงกับการเกิดขึ้นครั้งแรกของ fgh: 's / ^ fgh / jkl / g' (เครื่องหมายรูปหมวกสร้างความแตกต่างทั้งหมด)
Stephan202

2
เพียงเพื่อความแม่นยำ ... คุณหมายถึง "fgh ที่จุดเริ่มต้นของชื่อ" ไม่ใช่ "การเกิดขึ้นครั้งแรกของ fgh" / ^ fgh / จะตรงกับ "fghi" แต่ไม่ใช่ "efgh"
เดฟ Sherohman

@ สเตฟานนั่นเป็นตัวพิมพ์ผิดในส่วนของฉัน (แก้ไข)
nik

5
หากคุณไม่สามารถเข้าถึง "เปลี่ยนชื่อ" ได้ผลดีมาก รหัสอาจต้องมีเครื่องหมายคำพูดหากชื่อไฟล์ของคุณมีช่องว่าง for f in fgh*; do mv "$f" "$(echo $f | sed 's/^fgh/jkl/g')"; done
Dave Nelson

1
@ nik touch fghfilea fghfileb fghfilec fghfile\ dคำพูดโดยไม่ต้องเปลี่ยนชื่อรายการของไฟล์นี้จะโยนข้อผิดพลาด: ฉันขอแนะนำให้คำนึงถึงคำพูดของ @DaveNelson
luissquall

75

การเปลี่ยนชื่ออาจไม่ได้อยู่ในทุกระบบ ดังนั้นถ้าคุณไม่มีมันใช้เชลล์ตัวอย่างนี้ใน bash shell

for f in fgh*; do mv "$f" "${f/fgh/xxx}";done

1
ในโซลูชันsedนี้ไม่จำเป็นต้องใช้คำสั่ง อันนี้ง่ายกว่าคำตอบของ @ nik
Halil

xxx หมายถึงการทดแทนหรือไม่ ในกรณีของโปสเตอร์ต้นฉบับนั้นน่าจะเป็น "jkl"
Awinad

1
ทางออกที่สะอาดที่สุดของพวกเขาทั้งหมด
หัวหน้า MT

3
บางทีชี้ให้เห็นอย่างชัดเจนว่านี่เป็นส่วนขยาย Bash ซึ่งไม่มีอยู่ใน POSIX shหรือโดยทั่วไปในเชลล์อื่น ๆ
tripleee

น่ารัก - มีมุมที่คลุมเครือมากมายในโลก Unix - ไม่เคยเห็นมุมนี้มาก่อน
wcochran

40

ใช้mmv :

mmv "fgh*" "jkl#1"

1
ว้าวนี่เป็นวิธีที่ยอดเยี่ยมและง่ายในการแก้ปัญหา! ดีใจที่ได้รู้จักกับ mmv ขอบคุณ!
Hendeca

1
ขอบคุณ !!! ไม่เคยได้ยินเกี่ยวกับ mmv มาก่อน เพิ่งติดตั้งและเล่นกับมัน - ง่ายและทรงพลัง
นิคไรซ์

3
ถ้าคุณต้องการที่จะเปลี่ยนชื่อชุดซ้ำใช้ร่วมกับ; #1ตัวอย่าง:mmv ";fgh*" "#1jkl#2"
Alp

ทางออกที่หรูหรามาก!
นักเรียนตัวน้อยของแฟร์มาต์

1
สิ่งที่ฉันต้องการ จับภาพกลุ่มด้วย ' ' แล้วโทรกลับด้วย # 1, # 2, ... EX: mmv "my show ep 1080p." "my.show # 1 # 2" = my.show.001.avi
Lundy

20

มีหลายวิธีที่จะทำ (ไม่ใช่ทั้งหมดเหล่านี้จะทำงานบนระบบ unixy ทั้งหมด):

  • ls | cut -c4- | xargs -I§ mv fgh§ jkl§

    §อาจถูกแทนที่ด้วยสิ่งที่คุณเห็นว่าสะดวก คุณสามารถทำสิ่งนี้ได้find -execเช่นกัน แต่มันก็มีพฤติกรรมที่แตกต่างกันในหลาย ๆ ระบบดังนั้นฉันมักจะหลีกเลี่ยงสิ่งนั้น

  • for f in fgh*; do mv "$f" "${f/fgh/jkl}";done

    หยาบ แต่มีประสิทธิภาพตามที่พวกเขาพูด

  • rename 's/^fgh/jkl/' fgh*

    สวยจริง แต่การเปลี่ยนชื่อไม่ปรากฏใน BSD ซึ่งเป็นระบบยูนิกซ์ที่พบมากที่สุด

  • rename fgh jkl fgh*

  • ls | perl -ne 'chomp; next unless -e; $o = $_; s/fgh/jkl/; next if -e; rename $o, $_';

    หากคุณยืนยันการใช้ Perl แต่ไม่มีการเปลี่ยนชื่อในระบบของคุณคุณสามารถใช้สัตว์ประหลาดตัวนี้ได้

บางส่วนมีความซับซ้อนเล็กน้อยและรายการยังไม่สมบูรณ์ แต่คุณจะพบสิ่งที่คุณต้องการที่นี่สำหรับระบบยูนิกซ์


2
ฉันรักสัตว์ประหลาดชนิดนี้!
lefakir

ใช่ฉันยังคงมีจุดที่อ่อนแอสำหรับ Perl มากเกินไป :)
Iwein


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

13
rename fgh jkl fgh*

6
บนเครื่องของฉันนี่ทำให้เกิดข้อผิดพลาด 'Bareword "fgh" ไม่ได้รับอนุญาตในขณะที่ "เข้มงวด subs" ในการใช้ที่ (eval 1) บรรทัด 1'
Stephan202

@ Stephan202 เครื่องของคุณคืออะไร?
nik

Ubuntu 8.10 (perl v5.10.0 / 2009-06-26)
Stephan202

@ Stephan202 ฉันมีปัญหาเดียวกันคุณแก้ไขไหม (7 ปีต่อมา)
บัญชี

1
@whossname: ขอโทษจำไม่ได้จริงๆ (ตอบกลับช้าเนื่องจากวันหยุด)
Stephan202

8

การใช้find, xargsและsed:

find . -name "fgh*" -type f -print0 | xargs -0 -I {} sh -c 'mv "{}" "$(dirname "{}")/`echo $(basename "{}") | sed 's/^fgh/jkl/g'`"'

มันซับซ้อนกว่าโซลูชันของ @ nikแต่อนุญาตให้เปลี่ยนชื่อไฟล์ซ้ำ ตัวอย่างเช่นโครงสร้าง

.
├── fghdir
│   ├── fdhfilea
│   └── fghfilea
├── fghfile\ e
├── fghfilea
├── fghfileb
├── fghfilec
└── other
    ├── fghfile\ e
    ├── fghfilea
    ├── fghfileb
    └── fghfilec

จะเปลี่ยนเป็นสิ่งนี้

.
├── fghdir
│   ├── fdhfilea
│   └── jklfilea
├── jklfile\ e
├── jklfilea
├── jklfileb
├── jklfilec
└── other
    ├── jklfile\ e
    ├── jklfilea
    ├── jklfileb
    └── jklfilec

กุญแจสำคัญที่จะทำให้การทำงานด้วยxargsคือการเรียกเปลือกจาก xargs


1
ผมจะโพสต์อะไรเช่นนี้ แต่ก็จะได้เอาฉันชั่วโมงเพื่อให้ได้คำสั่งที่ถูกต้อง
ฆ Mendes

3

ในการติดตั้งสคริปต์การเปลี่ยนชื่อ Perl :

sudo cpan install File::Rename

มีการเปลี่ยนชื่อสองอย่างดังที่กล่าวไว้ในความคิดเห็นในคำตอบของ Stephan202 distros Debian ตามที่มีการเปลี่ยนชื่อ Perl Redhat / รอบต่อนาที distros มีการเปลี่ยนชื่อ C
OS X ไม่ได้มีการติดตั้งโดยค่าเริ่มต้น (อย่างน้อยใน 10.8) ไม่มี Windows / Cygwin


3

นี่คือวิธีการใช้ Groovy บรรทัดคำสั่ง:

groovy -e 'new File(".").eachFileMatch(~/fgh.*/) {it.renameTo(it.name.replaceFirst("fgh", "jkl"))}'

2

บน Solaris คุณสามารถลอง:

for file in `find ./ -name "*TextForRename*"`; do 
    mv -f "$file" "${file/TextForRename/NewText}"
done

คุณได้ครึ่งคะแนนสำหรับการอ้างอิงชื่อไฟล์ภายในลูป แต่for file in $(find)มีข้อบกพร่องพื้นฐานและไม่สามารถแก้ไขได้ด้วยการอ้างอิง หากfindผลตอบแทนที่./file name with spacesคุณจะได้รับforห่วง./file, name, withและspacesและจำนวนเงินไม่มีข้อความที่อยู่ภายในวงจะช่วย (หรือแม้กระทั่งมีความจำเป็น)
tripleee

2
#!/bin/sh

#replace all files ended witn .f77 to .f90 in a directory

for filename in *.f77
do 
    #echo $filename
    #b= echo $filename | cut -d. -f1
    #echo $b    
    mv "${filename}" "${filename%.f77}.f90"    
done

2

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

find . -type f -name "*\;*" | while read fname; do
    dirname=`dirname "$fname"`
    filename=`basename "$fname"`
    newname=`echo "$filename" | sed -e "s/;/ /g"`
    mv "${dirname}/$filename" "${dirname}/$newname"
done

สังเกตเห็นsedการแสดงออกซึ่งในตัวอย่างนี้แทนที่เกิดขึ้นทั้งหมดที่มีพื้นที่; แน่นอนควรเปลี่ยนนี้ตามความต้องการเฉพาะ


ขอบคุณมาก ! สคริปต์ที่ยอดเยี่ยม
Walter Schrabmair

1

การใช้เครื่องมือStringSolver (windows & Linux bash) ซึ่งดำเนินการโดยตัวอย่าง:

filter fghfilea ok fghreport ok notfghfile notok; mv --all --filter fghfilea jklfilea

ก่อนอื่นจะคำนวณตัวกรองตามตัวอย่างโดยที่อินพุตคือชื่อไฟล์และเอาต์พุต (ok และ notok สตริงที่กำหนดเอง) หากตัวกรองมีตัวเลือก - อัตโนมัติหรือถูกเรียกใช้โดยลำพังหลังจากคำสั่งนี้มันจะสร้างโฟลเดอร์okและโฟลเดอร์notokและผลักไฟล์ตามลำดับ

จากนั้นใช้ตัวกรองmvคำสั่งเป็นการย้ายแบบกึ่งอัตโนมัติซึ่งกลายเป็นอัตโนมัติด้วยตัวแก้ไข- อัตโนมัติ การใช้ตัวกรองก่อนหน้าด้วย --filter จะพบการจับคู่จากfghfileaถึงjklfileaและนำไปใช้กับไฟล์ที่ถูกกรองทั้งหมด


โซลูชันบรรทัดเดียวอื่น ๆ

วิธีอื่น ๆ ที่เทียบเท่าในการทำแบบเดียวกัน (แต่ละบรรทัดมีความเท่าเทียมกัน) ดังนั้นคุณสามารถเลือกวิธีที่คุณชอบได้

filter fghfilea ok fghreport ok notfghfile notok; mv --filter fghfilea jklfilea; mv
filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter fghfilea "mv fghfilea jklfilea"
# Even better, automatically infers the file name
filter fghfilea ok fghreport ok notfghfile notok; auto --all --filter "mv fghfilea jklfilea"

วิธีการแก้ปัญหาหลายขั้นตอน

หากต้องการค้นหาอย่างรอบคอบว่าคำสั่งทำงานได้ดีหรือไม่คุณสามารถพิมพ์คำสั่งต่อไปนี้:

filter fghfilea ok
filter fghfileb ok
filter fghfileb notok

และเมื่อคุณมั่นใจว่าตัวกรองนั้นดีใช้งานครั้งแรก:

mv fghfilea jklfilea

หากคุณต้องการทดสอบและใช้ตัวกรองก่อนหน้าให้พิมพ์:

mv --test --filter

หากการแปลงไม่ใช่สิ่งที่คุณต้องการ (เช่นแม้mv --explainคุณจะเห็นว่ามีบางอย่างผิดปกติ) คุณสามารถพิมพ์mv --clearเพื่อเริ่มการย้ายไฟล์ใหม่หรือเพิ่มตัวอย่างเพิ่มเติมmv input1 input2โดยที่ input1 และ input2 เป็นตัวอย่างอื่น

เมื่อคุณมั่นใจให้พิมพ์

mv --filter

และvoilà! การเปลี่ยนชื่อทั้งหมดทำได้โดยใช้ตัวกรอง

การปฏิเสธความรับผิด: ฉันเป็นผู้เขียนร่วมของงานนี้ทำเพื่อการศึกษา นอกจากนี้ยังอาจมีคุณลักษณะการผลิตทุบตีในไม่ช้า


1

มันง่ายกว่ามาก (ใน Mac ของฉัน) ทำสิ่งนี้ใน Ruby นี่คือ 2 ตัวอย่าง:

# for your fgh example. renames all files from "fgh..." to "jkl..."
files = Dir['fgh*']

files.each do |f|
  f2 = f.gsub('fgh', 'jkl')
  system("mv #{f} #{f2}")
end

# renames all files in directory from "021roman.rb" to "021_roman.rb"
files = Dir['*rb'].select {|f| f =~ /^[0-9]{3}[a-zA-Z]+/}

files.each do |f|
  f1 = f.clone
  f2 = f.insert(3, '_')
  system("mv #{f1} #{f2}")
end


1

เวอร์ชันการเปลี่ยนชื่อไฟล์มวลของฉัน:

for i in *; do
    echo "mv $i $i"
done |
sed -e "s#from_pattern#to_pattern#g” > result1.sh
sh result1.sh

ฉันชอบความสามารถในการตรวจสอบก่อนเรียกใช้สคริปต์
ardochhigh

สิ่งนี้จะแบ่งออกอย่างเด่นชัดในชื่อไฟล์ที่มีช่องว่างอัญประกาศหรืออักขระเมตาของเชลล์อื่น ๆ
tripleee

1

ฉันอยากจะแนะนำให้ใช้สคริปต์ของตัวเองซึ่งแก้ปัญหานี้ นอกจากนี้ยังมีตัวเลือกในการเปลี่ยนการเข้ารหัสชื่อไฟล์และการแปลงการรวม diacriticals เป็นอักขระที่รวมไว้ล่วงหน้าปัญหาที่ฉันมีเมื่อฉันคัดลอกไฟล์จาก Mac ของฉัน

#!/usr/bin/perl

# Copyright (c) 2014 André von Kugland

# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

$help_msg =
"rename.pl, a script to rename files in batches, using Perl
           expressions to transform their names.
Usage:
    rename.pl [options] FILE1 [FILE2 ...]
Where options can be:
    -v                      Verbose.
    -vv                     Very verbose.
    --apply                 Really apply modifications.
    -e PERLCODE             Execute PERLCODE. (e.g. 's/a/b/g')
    --from-charset=CS       Source charset. (e.g. \"iso-8859-1\")
    --to-charset=CS         Destination charset. (e.g. \"utf-8\")
    --unicode-normalize=NF  Unicode normalization form. (e.g. \"KD\")
    --basename              Modifies only the last element of the path.
";

use Encode;
use Getopt::Long;
use Unicode::Normalize 'normalize';
use File::Basename;
use I18N::Langinfo qw(langinfo CODESET);

Getopt::Long::Configure ("bundling");

# ----------------------------------------------------------------------------------------------- #
#                                           Our variables.                                        #
# ----------------------------------------------------------------------------------------------- #

my $apply = 0;
my $verbose = 0;
my $help = 0;
my $debug = 0;
my $basename = 0;
my $unicode_normalize = "";
my @scripts;
my $from_charset = "";
my $to_charset = "";
my $codeset = "";

# ----------------------------------------------------------------------------------------------- #
#                                        Get cmdline options.                                     #
# ----------------------------------------------------------------------------------------------- #

$result = GetOptions ("apply" => \$apply,
                      "verbose|v+" => \$verbose,
                      "execute|e=s" => \@scripts,
                      "from-charset=s" => \$from_charset,
                      "to-charset=s" => \$to_charset,
                      "unicode-normalize=s" => \$unicode_normalize,
                      "basename" => \$basename,
                      "help|h|?" => \$help,
                      "debug" => \$debug);

# If not going to apply, then be verbose.
if (!$apply && $verbose == 0) {
  $verbose = 1;
}

if ((($#scripts == -1)
  && (($from_charset eq "") || ($to_charset eq ""))
  && $unicode_normalize eq "")
  || ($#ARGV == -1) || ($help)) {
  print $help_msg;
  exit(0);
}

if (($to_charset ne "" && $from_charset eq "")
  ||($from_charset eq "" && $to_charset ne "")
  ||($to_charset eq "" && $from_charset eq "" && $unicode_normalize ne "")) {
  $codeset = langinfo(CODESET);
  $to_charset = $codeset if $from_charset ne "" && $to_charset eq "";
  $from_charset = $codeset if $from_charset eq "" && $to_charset ne "";
}

# ----------------------------------------------------------------------------------------------- #
#         Composes the filter function using the @scripts array and possibly other options.       #
# ----------------------------------------------------------------------------------------------- #

$f = "sub filterfunc() {\n    my \$s = shift;\n";
$f .= "    my \$d = dirname(\$s);\n    my \$s = basename(\$s);\n" if ($basename != 0);
$f .= "    for (\$s) {\n";
$f .= "        $_;\n" foreach (@scripts);   # Get scripts from '-e' opt. #
# Handle charset translation and normalization.
if (($from_charset ne "") && ($to_charset ne "")) {
  if ($unicode_normalize eq "") {
    $f .= "        \$_ = encode(\"$to_charset\", decode(\"$from_charset\", \$_));\n";
  } else {
    $f .= "        \$_ = encode(\"$to_charset\", normalize(\"$unicode_normalize\", decode(\"$from_charset\", \$_)));\n"
  }
} elsif (($from_charset ne "") || ($to_charset ne "")) {
    die "You can't use `from-charset' nor `to-charset' alone";
} elsif ($unicode_normalize ne "") {
  $f .= "        \$_ = encode(\"$codeset\", normalize(\"$unicode_normalize\", decode(\"$codeset\", \$_)));\n"
}
$f .= "    }\n";
$f .= "    \$s = \$d . '/' . \$s;\n" if ($basename != 0);
$f .= "    return \$s;\n}\n";
print "Generated function:\n\n$f" if ($debug);

# ----------------------------------------------------------------------------------------------- #
#                 Evaluates the filter function body, so to define it in our scope.               #
# ----------------------------------------------------------------------------------------------- #

eval $f;

# ----------------------------------------------------------------------------------------------- #
#                  Main loop, which passes names through filters and renames files.               #
# ----------------------------------------------------------------------------------------------- #

foreach (@ARGV) {
  $old_name = $_;
  $new_name = filterfunc($_);

  if ($old_name ne $new_name) {
    if (!$apply or (rename $old_name, $new_name)) {
      print "`$old_name' => `$new_name'\n" if ($verbose);
    } else {
      print "Cannot rename `$old_name' to `$new_name'.\n";
    }
  } else {
    print "`$old_name' unchanged.\n" if ($verbose > 1);
  }
}

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

ตามที่คาดการณ์ไว้โดย@kleopatraลิงก์ได้รับแล้วstale over time
y2k-shubham

1
@ y2k-shubham ไม่ใช่อีกแล้ว
André von Kugland

0

สิ่งนี้ใช้ได้กับฉันโดยใช้ regexp:

ฉันต้องการเปลี่ยนชื่อไฟล์เช่นนี้:

file0001.txt -> 1.txt
ofile0002.txt -> 2.txt 
f_i_l_e0003.txt -> 3.txt

usig [az | _] + 0 * ([0-9] +. ) regexp โดยที่ ([0-9] +. ) เป็นกลุ่มย่อยที่จะใช้กับคำสั่งเปลี่ยนชื่อ

ls -1 | awk 'match($0, /[a-z|\_]+0*([0-9]+.*)/, arr) { print   arr[0]  " "  arr[1] }'|xargs  -l mv

ผลิต:

mv file0001.txt 1.txt
mv ofile0002.txt 2.txt
mv f_i_l_e0003.txt 3.txt

ตัวอย่างอื่น:

file001abc.txt -> abc1.txt
ofile0002abcd.txt -> abcd2.txt 

ls -1 | awk 'match($0, /[a-z|\_]+0*([0-9]+.*)([a-z]+)/, arr) { print   arr[0]  " "  arr[2] arr[1] }'|xargs  -l mv

ผลิต:

  mv file001abc.txt abc1.txt
  mv ofile0002abcd.txt abcd2.txt 

เตือนระวัง


0

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

find . -type f -name "*.mkv" | while read fp; do 
fd=$(dirname "${fp}");
fn=$(basename "${fp}");
ext="${fn##*.}";
f="${fn%.*}";
new_fp="${fd}/${f}.avi"
mv -v "$fp" "$new_fp" 
done;

0

สคริปต์ทั่วไปเพื่อเรียกใช้sedนิพจน์ในรายการไฟล์ (รวมsedโซลูชันกับrenameโซลูชัน ):

#!/bin/sh

e=$1
shift

for f in $*; do
    fNew=$(echo "$f" | sed "$e")
    mv "$f" "$fNew";
done

เรียกใช้โดยส่งsedนิพจน์สคริปต์จากนั้นตามด้วยรายการไฟล์ใด ๆ เช่นเดียวกับเวอร์ชันของrename:

script.sh 's/^fgh/jkl/' fgh*

0

นอกจากนี้คุณยังสามารถใช้สคริปต์ด้านล่าง มันง่ายมากที่จะทำงานบน terminal ...

// เปลี่ยนชื่อหลายไฟล์พร้อมกัน

for file in  FILE_NAME*
do
    mv -i "${file}" "${file/FILE_NAME/RENAMED_FILE_NAME}"
done

ตัวอย่าง:-

for file in  hello*
do
    mv -i "${file}" "${file/hello/JAISHREE}"
done

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