ฉันเกลียดช่องว่างในชื่อไฟล์


61

มันง่าย ฉันไม่สามารถยืนได้เมื่อมีคนใช้พื้นที่เมื่อตั้งชื่อไฟล์ บางครั้งมันทำลายคำสั่งคอนโซลและทำให้เอาต์พุตของ ls น่าเกลียด

ความท้าทายคือการเขียนโปรแกรม (เฉพาะตัวอักษร ASCII) ซึ่ง

  1. เปลี่ยนชื่อไฟล์ทั้งหมด (รวมถึงไดเรกทอรี) ในไดเรกทอรีปัจจุบันเป็นรุ่นที่มีการลบช่องว่างหรือแทนที่ด้วย '_'
  2. ในการชนกันคุณจะต้องผนวกตัวระบุที่ไม่ซ้ำกัน (ขึ้นอยู่กับคุณ)
  3. ลงไปซ้ำในไดเรกทอรีย่อยทั้งหมด

คุณสามารถสมมติชื่อพา ธ สไตล์ UNIX ใครจะต้องใช้โปรแกรมนี้ในเครื่อง Windows บ้าง?

นี่คือรหัสกอล์ฟโปรแกรมที่สั้นที่สุดชนะ (#ascii ตัวอักษร) เนื่องจากฉันเกลียดช่องว่างมากแต่ละพื้นที่จะต้องถูกนับสองครั้ง

โปรดระบุภาษาคะแนนโปรแกรมและคำอธิบายโดยย่อเกี่ยวกับวิธีการเรียกใช้

โปรแกรมจะต้องรวบรวมและดำเนินการด้วยความพยายามอย่างสมเหตุสมผลบนเครื่อง linux ของฉัน

แก้ไข: ตามที่ Etan ร้องขอโครงสร้างไฟล์สำหรับการทดสอบต่อไปนี้เป็นสคริปต์ที่ฉันใช้เพื่อสร้างแผนผังไฟล์ที่เหมาะสม:

#!/bin/bash
rm -r TestDir

touchfiles()
{
    touch my_file
    touch my__file
    touch "my file"
    touch "my  file"
    touch " my_file  "
}

mkdir TestDir
cd TestDir

touchfiles

for dir in "Test Sub" Test_Sub "Te stSub" Te_stSub
do
    mkdir "$dir"
    cd "$dir"
    touchfiles
    cd ..
done

22
นี่คือการขอทานสำหรับวิธีการแก้ปัญหาที่ทำโดยไม่มีตัวอักษร ASCII
Dennis Jaheruddin

50
ตอนนี้ฉันต้องการเรียนรู้ช่องว่าง
BrunoJ

10
@BrunoJ ทำสิ่งนี้ใน Whitespace ก่อนอื่นคุณต้องพัฒนาระบบการเข้าถึงไฟล์ใน WS ฉันคิดว่ามันจะท้าทายมากกว่าความท้าทายที่แท้จริง
Nzall

7
รอให้ใครบางคนโพสต์คำตอบ C / C ++ เพื่อให้ฉันสามารถขโมยรวบรวมโพสต์ในรูปหกเหลี่ยมเป็นรหัสเครื่อง x86 ด้วยช่องว่าง ZERO! [หรืออาจ base64]
Mark K Cowan

10
ฉันเกลียดขีดเส้นใต้ในชื่อไฟล์ ใช้เครื่องหมายขีดคั่น
ดร. Rebmu

คำตอบ:


10

แกน Zsh + GNU - 48 ไบต์ (1 ช่องว่าง)

for x   (**/*(Dod))mv   -T  --b=t   $x  $x:h/${${x:t}// }

เป็นเรื่องแปลกที่คุณเกลียดช่องว่าง (ASCII) แต่ใช้ได้ดีกับแท็บและการขึ้นบรรทัดใหม่ แต่ฉันเดาว่ามันใช้ได้ทุกชนิด

zmvแก้ปัญหาการเปลี่ยนชื่อไฟล์เป็นจำนวนมากโดยสังเขป อย่างไรก็ตามมันยืนยันว่าเป้าหมายนั้นไม่เหมือนใคร ในขณะที่คุณสามารถเพิ่มคำต่อท้ายที่ไม่ซ้ำกันได้อย่างง่ายดายการเพิ่มคำต่อท้ายเฉพาะในกรณีที่จำเป็นต้องใช้ค่อนข้างมากต้องการการทำงานทั้งหมดซ้ำ ดังนั้นแทนที่จะวนซ้ำด้วยตนเองและพึ่งพาGNU mvเพื่อผนวกตัวระบุเฉพาะในกรณีที่มีการชนกัน ( --backupตัวเลือกรวมถึง--no-target-directoryในกรณีที่เป้าหมายเป็นไดเรกทอรีที่มีอยู่แล้วมิฉะนั้นmvจะย้ายแหล่งที่มาภายในไดเรกทอรีนั้น)

(od)เป็นตัวระบุแบบกลมเพื่อเรียงลำดับผลลัพธ์ด้วยไดเรกทอรีที่ปรากฏหลังเนื้อหา (เช่น find's -depth) Dรวมไฟล์ dot ไว้ใน glob :hและ:tมีการปรับเปลี่ยนประวัติศาสตร์คล้ายกับและdirnamebasename

mvบ่นว่ามันถูกเรียกให้เปลี่ยนชื่อไฟล์ด้วยตัวเองเพราะ glob มีชื่อไฟล์ที่ไม่มีช่องว่าง C'est la vie

เวอร์ชันที่ไม่ถูกปรับแต่ง:

for x in **/*\ *(Dod); do
  mv --no-target-directory --backup=numbered $x ${x:h}/${${x:t}// /}
done

1
นี่ไม่ได้เปลี่ยนชื่อไฟล์ของฉันเลย!
M.Herzkamp

@ M. Herzkamp โอ้ใช่แล้วzmvระเบิดออกมาก่อนmvมีโอกาสแยกแยะชน ตกลงฉันทำสิ่งนี้ด้วยตนเอง กลายเป็นความยาวเท่ากันทุกประการถ้าฉันข้ามไฟล์ dot และแม้กระทั่งบันทึกอักขระถ้าฉันทำไม่ได้
Gilles

1
ตอนนี้มันใช้งานได้ Btw: ฉันได้รวมบทลงโทษของช่องว่างไว้ในเวลาที่ฉันรู้สึกไม่พอใจกับช่องว่างจริง ๆ ) อย่างแดกดันฉันไม่ได้ยกเว้นช่องว่างเมื่อฉันโพสต์ความท้าทาย: P
M.Herzkamp

13

Bash 116 ไบต์, 16 ช่องว่าง

find . -depth -exec bash -c 'B=${0##*/}
M="${0%/*}/${B// /_}"
while [ -e "$M" ]
do M=$M.
done
mv "$0" "$M"' {} \;

ฉันไม่ได้ระงับข้อผิดพลาดที่จะได้รับอีกสองสามไบต์ สิ่งนี้จะไม่มีการชนกัน

หากfindคาดว่าจะไม่มี GNU ที่ไม่ใช่ posix สิ่งนี้สามารถทำให้สั้นลงได้อีก:

Bash 110 ไบต์ 15 ช่องว่าง

find -d -exec bash -c 'B=${0##*/}
M="${0%/*}/${B// /_}"
while [ -e "$M" ]
do M=$M.
done
mv "$0" "$M"' {} \;

การลบช่องว่างแทนการแทนที่จะใช้สองไบต์น้อยกว่า:

Bash 108 ไบต์ 15 ช่องว่าง

find -d -exec bash -c 'B=${0##*/}
M="${0%/*}/${B// }"
while [ -e "$M" ]
do M=$M.
done
mv "$0" "$M"' {} \;

หมายเหตุ: หากสามารถใช้แท็บแทนช่องว่างได้คุณจำเป็นต้องใช้พื้นที่เพียง 1 ช่องเท่านั้น (แท็บในกฎการจับคู่สำหรับการทดแทนที่บรรทัด 2)

ขอบคุณเดนนิสสำหรับการค้นหาข้อผิดพลาดในเครื่องหมายคำพูดคู่ (และการให้บริการโซลูชั่น)


11
พื้นที่พิเศษอยู่ข้างหลังพบว่ามีการเยาะเย้ยฉัน ??? ;-)
M.Herzkamp

@ M.Herzkamp ฉันแม้ว่ามันจะเป็นข้อผิดพลาดในการคัดลอกและวาง แต่จริงๆแล้วมี เดาฉันได้ 2 คะแนนมากขึ้น นอกจากนี้-depthใน GNU สามารถถูกแทนที่ด้วย-dแม้ว่ามันจะบ่นว่ามันเลิกใช้แล้ว ฉันไม่รู้เกี่ยวกับกฎของกอล์ฟฉันสามารถทำสิ่งนั้นได้หรือไม่?
pqnet

2
ตราบใดที่มันใช้ได้ฉันก็อนุญาต หากการคัดค้านกลายเป็นการลบในรุ่นอนาคตฉันอาจต้องกลับมาที่คำตอบนี้และลดระดับลงเนื่องจากไม่ถูกต้อง ;-)
M.Herzkamp

2
สิ่งนี้จะทำงานไม่ถูกต้องหากชื่อไฟล์ใดมีเครื่องหมายคำพูดคู่ ในการแก้ไขปัญหานี้คุณสามารถใช้bash -c 'B=${0##*/}...' {} \;แทนซึ่งสั้นกว่าจริง
เดนนิส

3
ฉันคิดว่าฉันจะเป็นผู้ชายคนนั้นเกิดอะไรขึ้นกับNตัวแปร? ไม่เคยมีคำจำกัดความ ...
Steven Penny

9

Python 180 ไบต์

from    os  import*
t,c,h='.',chdir,path
def g(p):
    c(p)
    for x   in  listdir(t):
        if h.isdir(x):g(x)
        n=x.replace(' ','')
        while h.exists(n):n+=t
        if' 'in x:rename(x,n)
    c(t*2)
g(t)

2 ช่องว่างเท่านั้นหากคุณใช้แท็บสำหรับเยื้อง :-)


ฉันเดาว่าคำตอบอื่น ๆ ส่วนใหญ่สามารถปรับปรุงคะแนนของพวกเขาโดยใช้แท็บแทนช่องว่างเช่นกัน
kasperd

แต่การส่งของคุณใช้ช่องว่างใช่มั้ย (+1 สำหรับรหัสการทำงาน)
M.Herzkamp

ผมไม่ทราบว่าวิธีการ ATT อักขระแท็บในคำตอบ ...
มานูเอ Paolini

2
แทนที่ด้วยแท็บ :-)
Emanuele Paolini

3
น่าเกลียดมากขนาดนี้ ... ฉันเดาว่าฉันจะขอมัน :(
M.Herzkamp

5

หากลำดับของส่วนต่อท้ายของไฟล์ที่มีการชนกันไม่จำเป็นต้องให้ก่อนหน้ากับไฟล์ที่มีอยู่แล้วการทำงานต่อไปนี้สำหรับฉัน:

bash / find / mv 84 ไบต์, 16 ช่องว่าง

find -depth -execdir bash -c '[ "${0//[^ ]}" ] && mv -{T,--b=t} "$0" "${0// }"' {} \;

bash / find / mv 82 ไบต์, 14 ช่องว่าง

find -depth -execdir bash -c '[ "${0//[^ ]}" ]&&mv -{T,-b=t} "$0" "${0// }"' {} \;

กอด&&เพื่อประหยัดพื้นที่สองไบต์

bash / find / mv 60 ไบต์, 11 ช่องว่าง

find -d -execdir bash -c 'mv -{T,-b=t} "$0" "${0// }"' {} \;

หยอดการป้องกันข้อผิดพลาดดังนั้นจึงได้รับข้อผิดพลาดจาก mv บนไฟล์ที่ไม่มีช่องว่างเริ่มต้นด้วย

แก้ไข: ลบเครื่องหมายคำพูดออกจาก{}ที่เดนนิสเตือน นอกจากนี้ยังได้รับอนุญาตfindให้กรีดร้องเกี่ยวกับการพกพาและการเลิกใช้งานในเวอร์ชั่นที่สั้นที่สุดซึ่งmvกำลังกรีดร้องเกี่ยวกับการย้ายไฟล์ที่อยู่ด้านบนของตัวเอง

แก้ไข 2: เพิ่ม-Tไปยังmvคำสั่งเพื่อหลีกเลี่ยงการซ้อนไดเร็กทอรีแทนการเปลี่ยนชื่อตามที่ pqnet ชี้ให้เห็น ใช้การขยายรั้งที่ค่าใช้จ่ายของตัวละครตัวหนึ่งมากกว่าเพียงแค่ใช้พื้นที่หนึ่ง


คุณสามารถใช้-dแทนและคุณไม่จำเป็นต้องมีคำพูดที่อยู่รอบ ๆ-depth {}
เดนนิส

@Dennis Yeah ฉันเห็นการ-dสนทนาเกี่ยวกับคำตอบของ pqnet แต่คิดว่าเนื่องจากฉันปิดเสียงmvกรีดร้องฉันจะหลีกเลี่ยงfindเสียงกรีดร้อง แม้ว่าฉันควรจะสั้นลงสำหรับเสียงกรีดร้อง และใช่ฉันมักจะพูด{}ด้วยเหตุผลบางอย่างแม้ว่าฉันรู้ว่าคุณไม่จำเป็นต้องในกรณีนี้ พลังแห่งนิสัยฉันเดา
Etan Reisner

1
เมื่อการชนเกิดขึ้นกับชื่อไดเรกทอรีมันจะใส่ลงไปในอีกชื่อหนึ่ง ใช้-Tตัวเลือกเพื่อmvหลีกเลี่ยงสิ่งนี้
pqnet

มันใช้งานได้และฉันพูดในสิ่งที่ท้าทายว่าภาคผนวกขึ้นอยู่กับคุณ +1
M.Herzkamp

4

NodeJS - 209 ไบต์, 3 ช่องว่าง

s=require('fs');function a(d){s.readdirSync(d).forEach(function(f){f=d+'/'+f;i=0;r=f;if(/ /.test(f)){r=f.replace(' ','');while(s.existsSync(r))r+=i++;s.renameSync(f,r)}s.statSync(r).isDirectory()&&a(r)})}a('.');

ฉันไม่คุ้นเคยกับ node.js ฉันจะเรียกใช้มันได้อย่างไร
M.Herzkamp

คุณจะต้องปฏิบัติการโหนดnodejs ; บันทึกไว้ในไฟล์และเรียกใช้node file.js
cPu1

7
TypeError: Object #<Object> has no method 'exists'ฉันได้รับการยกเว้น เดาที่: มันอยู่ในบรรทัดที่ 1! : D
M.Herzkamp

ฉันได้ทำการทดสอบแล้ว อย่างไรก็ตามฉันแทนที่มีอยู่กับคู่ที่ซิงโครนัส ลองตอนนี้ได้ไหม
cPu1

1
ฉันติดตั้งรุ่น 0.6.12 เท่านั้น นั่นอาจเป็นปัญหา
M.Herzkamp

2

Bash - 86 ไบต์

find    .   -d|while    IFS=""  read    f;do    t=${f##*/};mv   --b=t   -T  "$f"    "${f%/*}"/${t// /};done

อุ๊ปส์จะมีรูปลักษณ์
Subbeh

2
นอกจากนี้ยังมีการนับช่องว่างสองครั้ง ;-)
M.Herzkamp

คุณหมายความว่าอะไรกับการเว้นวรรคจะถูกนับเป็นสองเท่า
Subbeh

1
คุณสามารถบันทึกอักขระได้จำนวนมากโดยย่อ--backupไปที่--b

1
ใช่ตอนนี้มันใช้ได้กับชุดทดสอบของฉันเช่นกัน! +1
M.Herzkamp

2

Bash + Perl rename64

( renameเป็นสคริปต์ Perl บน Debian และอนุพันธ์ไม่ใช่คำสั่ง util-linux)

find . -depth -name "* *" -execdir rename 'y/ /_/' * \;

11
จะเกิดอะไรขึ้นถ้า "my file.txt" และ "my_file.txt" มีอยู่ทั้งคู่
M.Herzkamp

1
โอ้จริง .. กำลังดำเนินการในเร็ว ๆ นี้
german_guy

1
*ควร{}เป็นเพราะย่อมาจากนี้เท่านั้นเปลี่ยนชื่อไฟล์ที่มีชื่อปรากฏในไดเรกทอรีปัจจุบัน นี่ไม่ได้ต่อท้ายคำต่อท้ายในกรณีที่มีการปะทะกัน คุณสามารถบันทึกได้เล็กน้อยโดยไม่ต้องดำเนินการใด ๆ-name "* *"เนื่องจากrenameไม่สนใจไฟล์ที่ไม่มีการแปลงชื่อ
Gilles

2

POSIX sh+ GNU find+ GNU mv67 ASCII ไบต์ + หนึ่งช่องว่าง(ตามตัวอักษร)

find    -d  -exec   sh  -cf 'IFS=\ ;IFS=_   set $0;mv   --b=t   "$0"    "$*"'   {}  \;

ฉันไม่รู้ว่ามันเหมาะกับหรือไม่ แต่ด้วยลำดับของช่องว่างใด ๆนั้นถูกนำมารวมกันเป็นหนึ่งเดียว_- ฉันชอบมันอยู่ดี ที่จริงใด ๆลำดับแต่ชั้นนำ / เว้นวรรคต่อท้ายที่เป็น - เหล่านั้นจะถูกตัดทอนลงโดยอัตโนมัติ(ซึ่งยังเป็นที่ผมคิดว่าเป็นพฤติกรรมที่เป็นประโยชน์) ขอบคุณ Gilles ที่ชี้เรื่องนี้ออกมา

นี่ใช้ตัวคั่นเขตข้อมูลภายในเพื่อแยกเขตข้อมูล

มันค่อนข้าง ... ช่างพูด ...

... โอ้มนุษย์ ฉันรู้ว่าแท็บราคาถูก แต่ฉันคิดว่าอย่างน้อยก็ฉลาด ตอนนี้ฉันเพิ่งไปงานเลี้ยง ...


สิ่งนี้ใช้ได้กับชุดทดสอบตามที่คุณต้องการ แต่ไม่ตรงตามความต้องการ ฉันชอบมันเพราะฉันอาจจะเรียนรู้สิ่งใหม่ ฉันเดาว่าฉันจะต้องอ่านสิ่งIFSมหัศจรรย์นี้...
M.Herzkamp

1
@ M.Herzkamp - หากลักษณะการทำงานแตกต่างกันไปขึ้นอยู่กับว่ามีการตั้งค่าเป็นช่องว่างหรือไม่ คนส่วนใหญ่เกลียดชังเพราะพวกเขาไม่เข้าใจคุณสมบัติหลักสองประการ - มันทำงานเฉพาะในการขยาย( $expandไม่ใช่ (อดีต))และสิ่งที่กล่าวถึงเพียงอย่างเดียว ดูที่นี่
mikeserv

สิ่งนี้จะไม่เปลี่ยนชื่อไฟล์ภายในไดเรกทอรีที่ชื่อมีช่องว่าง การแก้ไขจะแทนที่ด้วย-exec -execdirÅนอกเหนือจากIFSที่คุณไม่ได้กล่าวถึงคือช่องว่างต่อท้ายจะถูกลบ โปรดทราบว่าในขณะที่คนอื่นสังเกตเห็นว่าคุณต้องการ-Tตัวเลือกmvเช่นกันสำหรับเมื่อเป้าหมายของการmvโทรเป็นไดเรกทอรีที่มีอยู่
Gilles

@Gilles - การตั้งค่าของฉันคือการใช้sh -c 'mkdir -p ../newtree/"$0"; ln "$0"/* ../newtree/$0 {} \;และ globs อื่น ๆ ในfind -type dคำสั่งเพื่อสร้างแผนภูมิของ hardlinks และจากนั้นให้ทำงานกับสิ่งเหล่านั้น แต่ฉันคาดเดาสองการเขียน code-golf สำหรับการย้าย จุดดีเกี่ยวกับช่องว่างนำหน้า / ต่อท้ายแม้ว่าฉันคิดว่านั่นเป็นพฤติกรรมที่ฉันต้องการ
mikeserv

@Gilles - แต่โดยวิธีการที่มันไม่ได้เป็นมุมแหลม - มันตั้งใจและมาตรฐานการควบคุมพฤติกรรม ฟิลด์แยกส่วนเป็นหนึ่งในไม่กี่อย่างมากในสเป็คเปลือกที่ไม่ได้มีคำพูดที่ไม่ได้ระบุหรือการดำเนินการตามที่กำหนดไว้ ไม่มีการค้ำประกันดังกล่าวมีอยู่zshเป็นฟังก์ชั่นในตัว zmvเช่น
mikeserv

2

PHP, 147 145 ไบต์2 1 พื้นที่s -> 146

function    s(){foreach(glob("*")as$n){is_dir($n)&&chdir($n)&s()|chdir("..");if($n<$r=strtr($n," ",_)){while(file_exists($r))$r.=_;rename($n,$r);}}}

ฟังก์ชั่นวนซ้ำ ทำงานด้วยs(".");

วนซ้ำglobผลลัพธ์สำหรับเส้นทางที่กำหนด:

  • หากไดเรกทอรี recurse
  • แทนที่ช่องว่างด้วยขีดล่าง
  • หากสตริงแตกต่างกัน
    • ในขณะที่มีการใช้ชื่อไฟล์ใหม่ให้ใส่เครื่องหมายขีดล่าง
    • เปลี่ยนชื่อไฟล์ / ไดเรกทอรี

php จะเปลี่ยนชื่อไฟล์บนเซิร์ฟเวอร์ ... ตอนนี้ฉันสงสัยว่าจะเปลี่ยนชื่อไฟล์ของลูกค้าได้อย่างไรเมื่อใดก็ตามที่พวกเขาเยี่ยมชมเว็บไซต์ของคุณ: D
M.Herzkamp

1

ทับทิม 121

require 'find'

Find.find('.') do |file|
  if file.chomp.match(/ /)
    File.rename(file, file.gsub(/ /, '_'))
  end
end

6
ยินดีต้อนรับสู่ Code Golf! ความคิดที่นี่ในความท้าทายของโค้ดกอล์ฟคือการใช้จำนวนอักขระน้อยที่สุด นั่นหมายความว่าคุณแน่นอนสามารถกำจัดบรรทัดว่างและแท็บและทำให้ชื่อตัวแปรตัวเดียว แต่คนมองหาทุกประเภทของวิธีที่สร้างสรรค์เพื่อลดจำนวนตัวอักษร
ไม่ใช่ชาร์ลส์ที่

ฉันได้รับข้อผิดพลาดว่าไดเรกทอรีไม่ว่างเปล่า:gam3.rb:5:in `rename': Directory not empty - ./Te stSub or ./Te_stSub (Errno::ENOTEMPTY) from gam3.rb:5 from /usr/lib/ruby/1.8/find.rb:39:in `find' from /usr/lib/ruby/1.8/find.rb:38:in `catch' from /usr/lib/ruby/1.8/find.rb:38:in `find' from gam3.rb:3
M.Herzkamp

1

Python, 187

165, รวม 22 จุดโทษสำหรับช่องว่าง

from os import*
u='_';j=path.join
for t,d,f in walk('.',0):
 for z in f+d:
  n=z.replace(' ',u)
  if n!=z:
   while path.exists(j(t,n)):n+=u
   rename(j(t,z),j(t,n))

166 โดยใช้เคล็ดลับ \ t ของ Emanuele :

เพียงช่องว่างเดียวในอันนี้!

from    os  import*
u='_';j=path.join
for t,d,f   in  walk('.',0):
    for z   in  f+d:
        n=z.replace(' ',u)
        if  n!=z:
            while   path.exists(j(t,n)):n+=u
            rename(j(t,z),j(t,n))

มันใช้งานได้สำหรับฉัน +1
M.Herzkamp

ลบช่องว่างที่จุดเริ่มต้นของบรรทัดและใช้แท็บ - ไม่มีช่องว่างดังนั้นให้นับเพียงครั้งเดียว
chill0r

@ chill0r นั่นคือสิ่งที่รุ่นที่สองคือ; ช่องว่างทั้งหมดจะถูกแทนที่ด้วยแท็บยกเว้นหนึ่ง (ยกเว้น SO ยังคงแสดงเป็นช่องว่าง)
Henry Keiter

1

LiveScript - 166

(แทนที่ช่องว่างด้วยแท็บ)

(a=->(s=require \fs)readdirSync(it)map (f)->f=it+'/'+f;r=f.replace /\s/g,i='';(while f!=r&&s.existsSync r=>r+=i++);s.statSync(f)isDirectory(s.renameSync f,r)&&a r) \.

ขึ้นอยู่กับnderscore ของ รุ่นที่ดีที่สุดของCPU1 's คำตอบ


ธิ! +1 ฉันจะลบความคิดเห็นของฉันก่อนหน้านี้เพื่อจัดระเบียบโพสต์นี้
M.Herzkamp

0

Bash 4+ 111 ไบต์

shopt -s dotglob globstar
for f in **
do
n=${f// /}
while [[ $f != $n && -e $n ]]
do n+=1
done
mv "$f" $n
done

1
ปัญหาเช่นเดียวกับรายการอื่น ๆ : คุณแทนที่ช่องว่างในไดเรกทอรีหลักและ mv ไม่พบพวกเขา นอกจากนี้คุณต้องเปลี่ยนทิศทางของการสำรวจมิฉะนั้นคุณจะเปลี่ยนชื่อไดเรกทอรีและ mv ไม่สามารถค้นหาไฟล์ภายใน
M.Herzkamp

0

Groovy, 139 ตัวอักษร

def c
c={
f->
def g=new File(f.parent,f.name.replaceAll('\\s',''))
f.renameTo(g)
!g.directory ?: g.eachFile(c)
}
new File('.').eachFile(c)

ตามความคิดเห็น @ edc65

Groovy จัดการการชน 259 ตัวอักษร

def c
c={
p,l,f->
def g=new File(p,f.name.replaceAll('\\s',''))
f==g?:
(g.exists()?f.renameTo(g.toString()+l.indexOf(f.name)):f.renameTo(g))
!g.directory?:g.eachFile(c.curry(g,g.list().toList()))
}
def r=new File('.')
r.eachFile(c.curry(r,r.list().toList()))

1
สิ่งนี้ไม่จัดการกับการชน
edc65

ตรวจสอบให้แน่ใจว่าไฟล์ถูกเปลี่ยนชื่อก่อนที่ไดเรกทอรีหลักของพวกเขาและว่าช่องว่างในไดเรกทอรีหลักจะไม่ถูกแทนที่
M.Herzkamp

ฉันแน่ใจว่ามันใช้ได้
เข้าสู่ระบบ

0

POSIX (ทดสอบบน zsh) + คำสั่ง Linux พื้นฐาน 151

export IFS='
'
for f in $(ls -R1);do export n=$(echo $f|tr ' ' '_');yes n|mv $f $n || yes n|mv $f `echo $n;echo $f|md5sum`
done

@ M.Herzkamp แก้ไขแล้ว
LinGeek

มีหลายสิ่ง: ฟังก์ชันของการส่งออก IFS และ c ใน ls -cR คืออะไร และคุณต้องการเวอร์ชัน mv สำหรับตัวเลือกใด -? (ฉันมี 8.13 และไม่รู้จักตัวเลือก) นอกจากนี้เพื่อให้ได้คะแนนที่ดีขึ้นคุณควรย่อชื่อตัวแปรของคุณ
M.Herzkamp

c แทนที่ช่องว่างด้วยการขึ้นบรรทัดใหม่ IFS หยุดช่องว่างเป็นตัวคั่น - กลับมาจากรุ่นเก่าและกำลังจะได้รับการแก้ไข
LinGeek

1
คุณพลาด mv ตัวที่สองในบรรทัดที่ 5 หรือไม่? และฉันคิดว่าหนึ่งเสียงสะท้อนในสายนั้นผิด
M.Herzkamp

1
$(ls -CR)เป็นของปลอมอย่างสมบูรณ์ -cตัวเลือกที่จะไม่ได้ผลและ-Rได้รับไฟล์ที่คุณได้โดยไม่ต้องไดเรกทอรีของพวกเขาซึ่งจะไม่มีจุดหมาย สถาปัตยกรรมของคุณพื้นฐานจะไม่จัดการชื่อไฟล์ที่มีการขึ้นบรรทัดใหม่ คุณต้องการset -fมิฉะนั้นชื่อไฟล์ที่มีไวด์การ์ดจะระเบิด exportไม่มีประโยชน์ ฉันสามารถเห็นสิ่งที่คุณพยายามทำอย่างไม่ชัดเจนเพื่อแยกไฟล์ แต่การวางท่อผิด
Gilles
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.