Rename special characters in filenames to underscore

Rename special characters in filenames to underscore

I am trying to change all characters that are not letters, numbers, dashes, dots, or underscores to an underscore in file names in a directory. So far I have the following:

ls *.mp3 | sed 's/[^0-9a-zA-Z._-]/_/g'

This works except that it just shows me the results, it does not actually change the names. What else do I need to do to get it to change the names?

答案1

Don't parse Ls. That seems to work well, but for complex cases it may fail.

With Bash's parameter expansion:

for f in *.mp3; do mv -- "$f" "${f//[!0-9a-zA-Z.-]/_}"; done

With Rename:

rename -- 's/[^0-9a-zA-Z.-]/_/g' *.mp3

If you only have standard POSIX tools and assuming no newline characters in the file names,

for f in *.mp3; do 
    mv -- "$f" "$(printf '%s\n' "$f" | sed 's/[^0-9a-zA-Z.-]/_/g')"
done

答案2

With zsh:

autoload -Uz zmv # best in ~/.zshrc
zmv '(*).mp3' '${f//[^0-9a-zA-Z_.-]/_}'

In zsh, ranges are based on codepoint value, so 0-9 includes 0123456789 only (and not 0123456789٠١٢٣٤٥٦٧٨۰۱۲۳۴۵۶۷۸߀߁߂߃߄߅߆߇߈०१२३४५६७८০১২৩৪৫৬৭৮੦੧੨੩੪੫੬੭੮૦૧૨૩૪૫૬૭૮୦୧୨୩୪୫୬୭୮௦௧௨௩௪௫௬௭௮౦౧౨౩౪౫౬౭౮౸౹౺౻౼౽౾೦೧೨೩೪೫೬೭೮൦൧൨൩൪൫൬൭൮෦෧෨෩෪෫෬෭෮๐๑๒๓๔๕๖๗๘໐໑໒໓໔໕໖໗໘༠༡༢༣༤༥༦༧༨༪༫༬༭༮༯༰༱༳၀၁၂၃၄၅၆၇၈႐႑႒႓႔႕႖႗႘፩፪፫፬፭፮፯፰០១២៣៤៥៦៧៨៰៱៲៳៴៵៶៷៸᠐᠑᠒᠓᠔᠕᠖᠗᠘᥆᥇᥈᥉᥊᥋᥌᥍᥎᧐᧑᧒᧓᧔᧕᧖᧗᧘᧚᪀᪁᪂᪃᪄᪅᪆᪇᪈᪐᪑᪒᪓᪔᪕᪖᪗᪘᭐᭑᭒᭓᭔᭕᭖᭗᭘᮰᮱᮲᮳᮴᮵᮶᮷᮸᱀᱁᱂᱃᱄᱅᱆᱇᱈᱐᱑᱒᱓᱔᱕᱖᱗᱘⁰⁴⁵⁶⁷⁸₀₁₂₃₄₅₆₇₈⅐⅑⅒⅓⅔⅕⅖⅗⅘⅙⅚⅛⅜⅝⅞⅟ↅ↉①②③④⑤⑥⑦⑧⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳⑴⑵⑶⑷⑸⑹⑺⑻⑽⑾⑿⒀⒁⒂⒃⒄⒅⒆⒇⒈⒉⒊⒋⒌⒍⒎⒏⒑⒒⒓⒔⒕⒖⒗⒘⒙⒚⒛⓪⓫⓬⓭⓮⓯⓰⓱⓲⓳⓴⓵⓶⓷⓸⓹⓺⓻⓼⓾⓿❶❷❸❹❺❻❼❽❿➀➁➂➃➄➅➆➇➉➊➋➌➍➎➏➐➑➓〇〡〢〣〤〥〦〧〨㉈㉉㉊㉋㉌㉍㉎㉏㉑㉒㉓㉔㉕㉖㉗㉘㉙㉚㉛㉜㉝㉞㉟㊱㊲㊳㊴㊵㊶㊷㊸㊹㊺㊻㊼㊽㊾㊿㋀㋁㋂㋃㋄㋅㋆㋇㋉㋊㋋㍘㍙㍚㍛㍜㍝㍞㍟㍠㍢㍣㍤㍥㍦㍧㍨㍩㍪㍫㍬㍭㍮㍯㍰㏠㏡㏢㏣㏤㏥㏦㏧㏩㏪㏫㏬㏭㏮㏯㏰㏱㏲㏳㏴㏵㏶㏷㏸㏹㏺㏻㏼㏽㏾꘠꘡꘢꘣꘤꘥꘦꘧꘨꣐꣑꣒꣓꣔꣕꣖꣗꣘꤀꤁꤂꤃꤄꤅꤆꤇꤈꧐꧑꧒꧓꧔꧕꧖꧗꧘꧰꧱꧲꧳꧴꧵꧶꧷꧸꩐꩑꩒꩓꩔꩕꩖꩗꩘꯰꯱꯲꯳꯴꯵꯶꯷꯸012345678

相关内容