Linux 如何使用bash脚本替换文件名中的空格

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2709458/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 19:58:35  来源:igfitidea点击:

How to replace spaces in file names using a bash script

linuxbashwhitespacefilenames

提问by armandino

Can anyone recommend a safe solution to recursively replace spaces with underscores in file and directory names starting from a given root directory? For example:

任何人都可以推荐一种安全的解决方案,从给定的根目录开始,在文件和目录名称中递归地用下划线替换空格吗?例如:

$ tree
.
|-- a dir
|   `-- file with spaces.txt
`-- b dir
    |-- another file with spaces.txt
    `-- yet another file with spaces.pdf

becomes:

变成:

$ tree
.
|-- a_dir
|   `-- file_with_spaces.txt
`-- b_dir
    |-- another_file_with_spaces.txt
    `-- yet_another_file_with_spaces.pdf

采纳答案by Paused until further notice.

Use rename(aka prename) which is a Perl script which may be on your system already. Do it in two steps:

使用rename(aka prename) 这是一个 Perl 脚本,它可能已经在您的系统上。分两步做:

find -name "* *" -type d | rename 's/ /_/g'    # do the directories first
find -name "* *" -type f | rename 's/ /_/g'

Based on Jürgen'sanswer and able to handle multiple layers of files and directories in a single bound using the "Revision 1.5 1998/12/18 16:16:31 rmb1" version of /usr/bin/rename(a Perl script):

基于Jürgen 的回答,并且能够使用“Revision 1.5 1998/12/18 16:16:31 rmb1”版本/usr/bin/rename(Perl 脚本)在单个范围内处理多层文件和目录:

find /tmp/ -depth -name "* *" -execdir rename 's/ /_/g' "{}" \;

回答by Michael Krelin - hacker

find . -depth -name '* *' \
| while IFS= read -r f ; do mv -i "$f" "$(dirname "$f")/$(basename "$f"|tr ' ' _)" ; done

failed to get it right at first, because I didn't think of directories.

一开始没做好,因为我没有想到目录。

回答by Jürgen H?tzel

A find/renamesolution. renameis part of util-linux.

一个查找/重命名的解决方案。重命名是 util-linux 的一部分。

You need to descend depth first, because a whitespace filename can be part of a whitespace directory:

您需要先降低深度,因为空白文件名可以是空白目录的一部分:

find /tmp/ -depth -name "* *" -execdir rename " " "_" "{}" ";"

回答by ghostdog74

bash 4.0

bash 4.0

#!/bin/bash
shopt -s globstar
for file in **/*\ *
do 
    mv "$file" "${file// /_}"       
done

回答by yabt

Here's a (quite verbose) find -exec solution which writes "file already exists" warnings to stderr:

这是一个(相当冗长的) find -exec 解决方案,它将“文件已存在”警告写入标准错误:

function trspace() {
   declare dir name bname dname newname replace_char
   [ $# -lt 1 -o $# -gt 2 ] && { echo "usage: trspace dir char"; return 1; }
   dir=""
   replace_char="${2:-_}"
   find "${dir}" -xdev -depth -name $'*[ \t\r\n\v\f]*' -exec bash -c '
      for ((i=1; i<=$#; i++)); do
         name="${@:i:1}"
         dname="${name%/*}"
         bname="${name##*/}"
         newname="${dname}/${bname//[[:space:]]/
#!/bin/bash
(
IFS=$'\n'
    for y in $(ls )
      do
         mv /`echo $y | sed 's/ /\ /g'` /`echo "$y" | sed 's/ /_/g'`
      done
)
}" if [[ -e "${newname}" ]]; then echo "Warning: file already exists: ${newname}" 1>&2 else mv "${name}" "${newname}" fi done ' "${replace_char}" '{}' + } trspace rootdir _

回答by jojohtf

Here's a reasonably sized bash script solution

这是一个合理大小的 bash 脚本解决方案

#!/usr/bin/perl

&rena(`find . -type d`);
&rena(`find . -type f`);

sub rena
{
    ($elems)=@_;
    @t=split /\n/,$elems;

    for $e (@t)
    {
    $_=$e;
    # remove ./ of find
    s/^\.\///;
    # non ascii transliterate
    tr [0-7][_];
    tr [
 IFS=$'\n';for f in `find .`; do file=$(echo $f | tr [:blank:] '_'); [ -e $f ] && [ ! -e $file ] && mv "$f" $file;done;unset IFS
0-][_]; # special characters we do not want in paths s/[ \-\,\;\?\+\'\"\!\[\]\(\)\@\#]/_/g; # multiple dots except for extension while (/\..*\./) { s/\./_/; } # only one _ consecutive s/_+/_/g; next if ($_ eq $e ) or ("./$_" eq $e); print "$e -> $_\n"; rename ($e,$_); } }

回答by degi

This one does a little bit more. I use it to rename my downloaded torrents (no special characters (non-ASCII), spaces, multiple dots, etc.).

这个做的多一点。我用它来重命名我下载的种子文件(没有特殊字符(非 ASCII)、空格、多个点等)。

detox -r <folder>

回答by user1060059

This only finds files inside the current directory and renames them. I have this aliased.

这只会在当前目录中查找文件并重命名它们。我有这个别名。

find ./ -name "* *" -type f -d 1 | perl -ple '$file = $_; $file =~ s/\s+/_/g; rename($_, $file);

find ./ -name "* *" -type f -d 1 | perl -ple '$file = $_; $file =~ s/\s+/_/g; rename($_, $file);

回答by Juan Sebastian Totero

I found around this script, it may be interesting :)

我发现了这个脚本,它可能很有趣:)

##代码##

回答by user78274

you can use detoxby Doug Harple

你可以使用detox道格哈普尔

##代码##