เปลี่ยนทรีไดเรกทอรีทั้งหมดเป็นชื่อตัวพิมพ์เล็ก


12

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

ยกตัวอย่างเช่นหน้าอาจมีการเชื่อมโยงเช่นในขณะที่ไฟล์ที่เกิดขึ้นจริง<a href='/subfolder/PageName.asp'> /subfolder/pagename.aspในทำนองเดียวกันกับภาพ - อาจจะมี<img src='spacer_sm.gif'>Spacer_Sm.gif

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

แม้ว่าจะมีคำสั่ง unix ที่มีการสลับ case-insensitve แต่ฉันกำลังใช้ php ดังนั้นคำสั่งระบบไฟล์บางตัวก็ไม่มีตัวเลือกสำหรับความไวของ case


2
ดูคำถามก่อนหน้านี้ที่คล้ายกัน ฉันโพสต์คำตอบที่ง่ายขึ้นที่นี่อีกครั้งเพราะคำถามนั้นค่อนข้างเจาะจง
Gilles 'ดังนั้น - หยุดความชั่วร้าย'

คำตอบ:


8

ฉันไม่รู้ว่ายูนิกซ์ของคุณมีรสชาติrenameหรือไม่ Linuxes หลายตัวมีและเป็นส่วนหนึ่งของ perl-package หากคุณค้นหาที่เก็บ

find ./ -depth -exec rename -n 'y/[A-Z]/[a-z]/' {} ";"

เหนือกว่ารุ่นด้วย

rename -n 

ไม่ได้ทำการกระทำจริง ๆ แต่พิมพ์เฉพาะสิ่งที่จะทำ คุณไม่ใช้ -n เพื่อทำสิ่งนั้นจริง


ส่วน 'ภาษา' หรือ regex คือ'y/[A-Z]/[a-z]/'อะไร
user394

เนื่องจากrenameเป็นส่วนหนึ่งของperlแพ็คเกจฉันเดาว่า perl แต่รูปแบบนั้นถูกใช้sedด้วยเช่นกันและอาจจะAWKเป็นเช่นกัน ฉันรู้ แต่เพียงว่าsedเงียบดี ฉันแปลyไปtranslateหรือmapแต่ฉันไม่รู้ว่าต้นกำเนิดของตัวละครนั้นมาจากไหน
ผู้ใช้ไม่ทราบ

จะต้องเป็น Perl Regex - Gilles ในคำตอบของเขาบอกว่าrenameเป็นสคริปต์ Perl
user394

ใช่และคุณอาจใช้ Perl regexs เพื่อแก้ไขชื่อไฟล์ซึ่งไม่จำเป็นต้องสรุปจากการเขียนใน perl แต่อาจเป็นคำถามที่น่าสนใจ
ผู้ใช้ไม่ทราบ

9

zsh

zmv -o-i '(**/)(*)' '$1${2:l}'

คำอธิบาย: zmvเปลี่ยนชื่อไฟล์ที่ตรงกับรูปแบบตามข้อความการแทนที่ที่กำหนด -o-iผ่าน-iตัวเลือกให้กับแต่ละmvคำสั่งภายใต้ประทุน (ดูด้านล่าง) ในข้อความทดแทน$1, $2ฯลฯ เป็นกลุ่มวงเล็บต่อเนื่องในรูปแบบ **หมายถึงไดเรกทอรีทั้งหมด (ย่อย) * ซ้ำ ๆ สุดท้าย(/)ไม่ใช่กลุ่มที่ถูกวงเล็บ แต่เป็นตัวระบุแบบกลมหมายถึงการจับคู่ไดเรกทอรีเท่านั้น ${2:l}แปลง$2เป็นตัวพิมพ์เล็ก

Perl เปลี่ยนชื่อ

ที่นี่ฉันใช้สคริปต์เปลี่ยนชื่อ Perl ที่ Debian และ Ubuntu จัดส่งเป็น/usr/bin/prename(โดยทั่วไปมีให้renameเช่นกัน) ด้วย bash ≥4หรือ zsh:

shopt -s globstar  # only in bash
rename 's!/([^/]*/?)$!\L/$1!' **/*

กับกระสุนอื่น ๆ :

find . -depth -exec rename -n 's!/([^/]*/?)$!\L/$1!' {} +

แบบพกพา

ซ้ำ:

find . -depth -exec sh -c '
    t=${0%/*}/$(printf %s "${0##*/}" | tr "[:upper:]" "[:lower:]");
    [ "$t" = "$0" ] || mv -i "$0" "$t"
' {} \;

การใช้-depthเพื่อให้แน่ใจว่ามีการประมวลผลไดเรกทอรีที่ซ้อนกันอย่างลึกซึ้งก่อนบรรพบุรุษของพวกเขา


1

มันไม่ทำงานในโครงสร้างไดเรกทอรีต่อไปนี้:

JKL/
deF/
ABC/DEf
ABC/gHi
ghi/jkL

นี่คือตัวอย่างที่ใช้งานได้:

for i in `find | sort -r | sed '$d'`; do \
   b=${i%/*}; e=${i##*/}; mv $i $b'/'${e,,}; done

สำหรับคำอธิบายเกี่ยวกับbและevars:

man bash

จากนั้นใช้ลำดับของคีย์ต่อไปนี้: /,,Enterbb


0

คำตอบที่ได้รับการยอมรับไม่ได้ผลสำหรับฉันเพราะมันพยายามเปลี่ยนไดเรกทอรีทั้งหมดในครั้งเดียว ฉันพบโซลูชันอื่นใน stackexchange คล้ายกับพกพาจาก Gilles ด้านบน: จาก Baramin -
/programming/4268591/unix-rename-files-directories-to-uppercase

ฉันคัดลอกมาที่นี่:

find . -depth | \
while read LONG; do
   SHORT=$( basename "$LONG" | tr '[:lower:]' '[:upper:]' )
   DIR=$( dirname "$LONG" )
   if [ "${LONG}" != "${DIR}/${SHORT}"  ]; then
     mv "${LONG}" "${DIR}/${SHORT}"
   fi
done

ซึ่งฉันเปลี่ยนคำสั่ง tr เป็น ie: sed s / cat / dog / g

ขอบคุณใด ๆ ไปที่ Baramin ที่ลิงค์ด้านบน

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