วิธีการเปลี่ยนชื่อหลายไฟล์ตามลำดับจากบรรทัดคำสั่ง?


15

วิธีการเปลี่ยนชื่อไฟล์ดังต่อไปนี้

AS1100801000002.RAW7AGS 
AS1100801001008.RAW7AH4
AS1100801002001.RAW7AH9
AS1100801003002.RAW7AHE
AS1100801004009.RAW7AHT
AS1100801005002.RAW7AHY
AS1100801010002.RAW7AJ3

เป็นชื่อใหม่

AS1.txt
AS2.txt
AS3.txt
AS4.txt
AS5.txt
AS6.txt
AS7.txt

คำตอบ:


22

renameเครื่องมือที่มาพร้อมกับอูบุนตูสวยร้อนที่จัดเรียงของสิ่งนี้ คุณสามารถฝังการแสดงออก Perl น้อยเช่น:

rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *

นั่นจะแสดงให้คุณเห็นว่ามันจะทำอะไร ลบ-nเพื่อให้เป็นการออกกำลังกายแบบสด

สิ่งนี้ใช้งานได้โดยการกำหนดตัวแปรอย่างหยาบและเพิ่มแต่ละไฟล์ที่เราตี หากคุณกำลังจะมีมากกว่า 10 ไฟล์ที่ผมขอแนะนำให้ใช้บางศูนย์ padding sprintfใน ต่อไปนี้ดีถึง999:

rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *

... แต่มันก็ง่ายพอที่จะขยาย


4

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

N=1
for X in AS*RAW*; do
  mv $X AS$N.txt
  N=$(($N+1))
done

3

ที่จะปรับปรุง @ Oli ของคำตอบที่renameเครื่องมือรุ่น 1.600โดยอริสโตเติล Pagaltzis$Nจริงมีเคาน์เตอร์ในตัว

ดังนั้นสิ่งที่คุณต้องการคือ

rename 's/AS.*/AS$N/' *

ติดตั้ง,

  1. brew install renameหรือดาวน์โหลดสคริปต์
  2. บันทึกลงในไดเรกทอรีบนเส้นทางระบบของคุณ (ปกติ/usr/local/bin/brewหรือ/usr/bin)

3
ดูเหมือนว่าจะเป็นเครื่องมือที่แตกต่างที่มีชื่อเดียวกัน ค่าเริ่มต้นของ Ubuntu renameนั้นเป็นรหัสผ่านล่วงหน้า อาจดีกว่านี้ แต่คุณอาจต้องการเพิ่มคำแนะนำในการติดตั้งเพื่อให้คำตอบนี้มีค่ามากขึ้น
Oli

1
@Oli โทรดี! อัปเดต
Atav32

2

renameช่วยให้คุณกำหนดโดยตรงกับ$_ซึ่งเหมาะสำหรับปัญหานี้

แม้ว่าข้อโต้แย้งของรหัสที่เราส่งไปยังrenameโปรแกรมอรรถประโยชน์ของPerl มักจะทำการจับคู่และทดแทน (ด้วยs/) และเป็นที่ยอมรับโดยสิ้นเชิงในการแก้ปัญหานี้ในแบบที่ไม่จำเป็นสำหรับกรณีเช่นนี้ซึ่งคุณไม่ได้ตรวจสอบหรือ การนำข้อความชื่อไฟล์เก่ามาใช้ซ้ำ renameช่วยให้คุณเขียนเพียงเกี่ยวกับการใด ๆรหัส Perl s/ /eและมันไม่จำเป็นต้องได้รับการฝังอยู่ภายใน ฉันขอแนะนำให้ใช้คำสั่งเช่นนี้:

rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *

หรือหากคุณรู้สึกอยากโกนหนวดสักสองสามตัว:

rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *

(มันสามารถทำให้สั้นลงได้ แต่ไม่ลดทอนความชัดเจน)

ทั้งสองคำสั่งเหล่านั้นทำสิ่งเดียวกัน แต่ละรายการแสดงการดำเนินการเปลี่ยนชื่อที่จะดำเนินการ เมื่อคุณลองใช้แล้วคุณจะพอใจกับผลลัพธ์ให้เรียกใช้อีกครั้งโดยไม่มี-nตัวเลือก ขณะที่เขียนนี้จะผลิตชื่อไฟล์AS01.txt, AS02.txt, ... , AS10.txt, AS11.txtและอื่น ๆ คุณสามารถแก้ไขได้ตามต้องการจากนั้นลบ-nเมื่อคุณต้องการสิ่งที่คุณเห็น

หากคุณต้องการแผ่นที่มีความกว้างมากกว่า 2 ให้แทนที่2ด้วยจำนวนที่มากขึ้น ตัวอย่างเช่นถ้าด้วยเหตุผลบางอย่างที่คุณต้องการชื่อไฟล์ที่ต้องการAS00000000000001.txtคุณจะเข้ามาแทนที่ด้วย%02d %014dหากคุณไม่ต้องการ padding ที่ทั้งหมด - แม้ว่าที่จะทำให้ไฟล์ของคุณปรากฏในคำสั่งที่ไม่ใช่ตัวเลขเมื่อคุณรายการพวกเขาในภายหลัง! - แล้วคุณสามารถแทนที่มีเพียง%02d%d

มันทำงานอย่างไร เชลล์ของคุณขยาย *เข้าไปในรายการไฟล์ก่อนที่มันจะรันrenameคำสั่ง รายการจะถูกจัดเรียงตามพจนานุกรม (เช่นตัวอักษร) ตามการตั้งค่าตำแหน่งที่ตั้งปัจจุบันของคุณ renameรับชื่อไฟล์เป็นอาร์กิวเมนต์บรรทัดคำสั่งและประมวลผลตามลำดับที่ปรากฏ นิพจน์++$iประเมินค่ามากกว่าหนึ่งค่าปัจจุบันของตัวแปร$iและตั้งค่าตัวแปรเป็นค่า$iที่เพิ่มขึ้นใหม่ ค่านี้ถูกส่งผ่านไปยังsprintfซึ่งจัดรูปแบบและวางไว้ในข้อความอื่น ข้อความนี้ถูกกำหนดให้กับตัวแปรพิเศษโดยตรง$_ซึ่งเก็บชื่อไฟล์ เนื่องจากrenameไฟล์กระบวนการตามลำดับที่ส่งเป็นอาร์กิวเมนต์จะถูกนับตามลำดับ


คุณอาจสังเกตเห็นความคล้ายคลึงกับคำตอบของ Oli !

ทั้งประกาศและเพิ่มตัวแปรตัวนับและทั้งคู่ก็ใช้sprintfวิธีเดียวกันในการฝังค่าของตัวนับนั้นไปทางด้านซ้ายด้วยค่าศูนย์ในข้อความอื่น ๆ ของชื่อไฟล์ใหม่ (ข้อมูลในคำตอบอย่างใดอย่างหนึ่งเกี่ยวกับวิธีการแผ่นด้วยศูนย์ - และเปลี่ยนความกว้างช่องว่างภายใน -. แม้ใช้อย่างเท่าเทียมกันทั้งสอง) เหตุผลที่พวกเขามีความคล้ายคลึงกันเพื่อให้เป็นว่าวิธีการในการที่คำตอบเก่าเป็นจริงทำเพียงแค่นี้1แต่ ด้วยขั้นตอนพิเศษที่มีประโยชน์สำหรับปัญหามากมาย แต่ไม่จำเป็นจริงๆสำหรับขั้นตอนนี้

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

rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *

ส่วนระหว่างs/.+/และ/eในคำสั่งนั้นตอนนี้เหมือนกับนิพจน์ที่ฉันกำหนดให้$_(เช่นรหัสทางด้านขวาของ=โอเปอเรเตอร์) ในคำสั่งแรกในคำตอบนี้

  • ตัวs/ ดำเนินการพยายามจับคู่ข้อความ (ชื่อไฟล์ที่เชลล์ของคุณขยายจาก*และผ่านเป็นอาร์กิวเมนต์บรรทัดคำสั่งเมื่อรันrename) ด้วยนิพจน์ทั่วไปและทำการทดแทน /กำลังใช้เป็นตัวคั่นเพื่อแยกส่วนต่าง ๆ ของsนิพจน์ ส่วนแรก.+,, คือการแสดงออกปกติ; มันตรงกับใด ๆ1ตัวอักษร ( .)และไม่ให้หนึ่งครั้งหรือมากกว่า (+ ) เนื่องจากชื่อไฟล์จะไม่ว่างเปล่า - มีความยาวอย่างน้อยหนึ่งตัวอักษร - นี่เป็นวิธีหนึ่งในการจับคู่ชื่อไฟล์1ไฟล์
  • จากนั้นก็จะผลิตข้อความจากการแข่งขันแต่ละครั้ง - นั่นคือจากแต่ละชื่อไฟล์ทั้งหมด - our $i; sprintf "AS%02d.txt", ++$iประกอบด้วย สิ่งนี้จะสร้างชื่อไฟล์ใหม่ โดยทั่วไปแล้วหนึ่งใช้s/ในการผลิตข้อความที่(a)แทนที่ข้อความที่ตรงกับเพียงส่วนหนึ่งของชื่อไฟล์หรือ(b)ขึ้นอยู่กับข้อความที่ตรงกันในบางวิธี (ตัวอย่างเช่นมันอาจใช้ตัวแปรพิเศษเช่น$&ขยาย การแข่งขัน) ในกรณีนี้ข้อความที่ตรงกันไม่ได้ถูกใช้งานเลย
  • โดยปกติแล้วข้อความที่our $i; sprintf "AS%02d.txt", ++$iถูกแทนที่จะถูกใช้เป็นชื่อไฟล์ไม่ใช่เรียกใช้เป็นรหัส แต่การ/eตั้งค่าสถานะในตอนท้ายทำให้ข้อความนั้นถือว่าเป็นซอร์สโค้ด Perl และประเมินและใช้ค่าที่สร้างขึ้นโดยการทำเช่นนั้น (ในกรณีนี้คือค่าส่งคืนของsprintfฟังก์ชันในตัวของ Perl ) เป็นชื่อไฟล์ใหม่

แม้ว่าฉันคิดว่าวิธีการที่ฉันแสดงไว้ที่นี่เป็นวิธีการที่ชัดเจนและง่ายกว่าสำหรับปัญหานี้มากกว่าวิธีการอื่นที่ใช้s/ด้วย/eแต่ก็เป็นเรื่องดีที่จะต้องตระหนักถึงเทคนิคนั้นเพราะมันเหมาะสมกับปัญหาการเปลี่ยนชื่อไฟล์อื่น ๆ หรือบางส่วนของชื่อไฟล์ต้นฉบับจะถูกตรวจสอบและ / หรือเก็บไว้ ฉันแนะนำโพสต์บล็อกนี้โดยOli (ผู้เขียนคำตอบนั้นด้วย ) ซึ่งรวมถึงตัวอย่างดังกล่าว

1 เทคนิคมีคือความแตกต่างในการทำงานของ$_ =คำสั่งและs/ /eคำสั่ง ในการแสดงออกปกติ.+ก็ไม่เป็นความจริงอย่างเคร่งครัดที่.ตรงกับใด ๆของตัวละครเพราะมันไม่ตรงกับขึ้นบรรทัดใหม่ คุณอาจไม่ควรใช้ชื่อไฟล์กับการขึ้นบรรทัดใหม่ แต่คุณสามารถและบางครั้งไฟล์จะถูกตั้งชื่อโดยวิธีนี้โดยไม่ตั้งใจ ถ้าคุณรู้สึกว่ามันแตกต่างการส่งออกของกับที่ของrename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar' rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'หากต้องการ.จับคู่บรรทัดใหม่ให้ใช้sแฟล็กซึ่งจะสิ้นสุดที่ (ด้วยe) นั่นคือการเขียนในตอนท้ายแทน/se/e


0

สมมติว่าไฟล์ที่คุณต้องการเปลี่ยนชื่อนั้นอยู่~/Adirและไฟล์เหล่านี้เป็นไฟล์เดียวในโฟลเดอร์นี้จากนั้น:

n=0
for f in $( ls ~/Adir | sort ) ; do
    n=$(( n+1 ))
    mv -n "$f" "AS${n}.txt"
done

สคริปต์นี้จะดูที่ไฟล์แต่ละไฟล์~/Adirและเปลี่ยนชื่อเป็นAS1.txt, AS2.txt, ...หากไม่มีไฟล์อยู่ (จะไม่มีการเขียนทับ) ~/Adirนั่นเป็นเหตุผลที่คุณควรให้แน่ใจว่าเหล่านี้เป็นไฟล์เฉพาะใน sortคำสั่งในกรณีที่คุณต้องการไฟล์เพื่อให้สั่งซื้อครั้งแรก


0

แม้ว่า OP ต้องการตัวเลือกบรรทัดคำสั่ง แต่ก็ยังมีให้ใช้เป็นตัวเลือก GUI ใน Nautilus และค่อนข้างง่าย

เลือกไฟล์ที่จำเป็นทั้งหมดแล้วกด F2 มีตัวเลือกที่เรียกว่าตัวเลขอัตโนมัติ คุณสามารถต่อท้ายข้อความที่คุณต้องการ

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