怎么把文件名中的空格全去掉

sh/bash/dash/ksh/zsh等Shell脚本
DerekTan
帖子: 33
注册时间: 2007-05-22 10:48
送出感谢: 0
接收感谢: 0
联系:

怎么把文件名中的空格全去掉

#1

帖子 DerekTan » 2010-01-07 14:20

这个问题还有点小难的,我想不到好一点的方法

从光盘上拷来一个文件夹,文件夹包含子目录,子目录里面又有文件,反正还挺多的,好几层~~
这里面的目录名和文件名,有不少包含空格

我想要把目录名、文件名中的空格全部去掉,各位有什么好办法不?

我一开始的想法是find . -name "*", 然后把找到的文件列表传给mv。 实际这样做不行,因为会出现把目录名改了以后,原来find出来的文件路径已经改掉了,mv就不成功了……(囧,我讲清楚没有?)

先谢谢啦:)
p0p0007123
帖子: 40
注册时间: 2010-01-04 13:55
送出感谢: 0
接收感谢: 0

Re: 怎么把文件名中的空格全去掉

#2

帖子 p0p0007123 » 2010-01-07 14:30

不晓得,帮你顶一下。 :em09
头像
yaoms
帖子: 4953
注册时间: 2007-10-19 14:51
来自: 深圳
送出感谢: 0
接收感谢: 2 次

Re: 怎么把文件名中的空格全去掉

#3

帖子 yaoms » 2010-01-07 14:38

代码: 全选

for filename in `find . -name "*"`
do newname="${filename// /}"
newdirname=`dirname $newname`
mkdir -p /newdir/"$newdirname"
cp -v "$filename" /newdir/"$newname"
done
Nothing 有事请发邮件到 yms541 AT gmail.com
alias 爱慕颇雷尔='mplayer'
DerekTan
帖子: 33
注册时间: 2007-05-22 10:48
送出感谢: 0
接收感谢: 0
联系:

Re: 怎么把文件名中的空格全去掉

#4

帖子 DerekTan » 2010-01-07 15:26

yaoms 写了:

代码: 全选

for filename in `find . -name "*"`
do newname="${filename// /}"
newdirname=`dirname $newname`
mkdir -p /newdir/"$newdirname"
cp -v "$filename" /newdir/"$newname"
done
谢谢yaoms,不过可能有点问题,在for filename in `find . -name "*"`这里,find出来的文件名里面已经包含空格了,比如“a b",$filename会得到两次值,一个是a,一个是b...
头像
darkfish
帖子: 90
注册时间: 2009-09-18 10:03
来自: 北京
送出感谢: 0
接收感谢: 0
联系:

Re: 怎么把文件名中的空格全去掉

#5

帖子 darkfish » 2010-01-07 16:38

试试

代码: 全选

 rename 's/([^\ ]*) +(.*)/$1$2/' *
头像
darkfish
帖子: 90
注册时间: 2009-09-18 10:03
来自: 北京
送出感谢: 0
接收感谢: 0
联系:

Re: 怎么把文件名中的空格全去掉

#6

帖子 darkfish » 2010-01-07 16:42

哦,也有问题,只能是一串空格隔开的文件名。(如果反复用N次的话,应该可以解决,嘿嘿)
头像
xunknown
帖子: 22
注册时间: 2010-01-03 20:04
送出感谢: 0
接收感谢: 0

Re: 怎么把文件名中的空格全去掉

#7

帖子 xunknown » 2010-01-08 0:19

用下面在脚本,经过测试:

#!/bin/sh
#使用bash做为默认shell

#create by Alpha @2010-01-08
#本程序的功能是遍历指定目录及其所有子目录,将所有文件名(目录除外)中的空格替换为下划线,

#convert whitesapce to '_' in filename
rename()
{
for file in "$1"/*
do
if [ -d "$file" ]; then
rename "$file" #递归调用,遍历所有子目录
elif [ -f "$file" ]; then
dir=`dirname "$file"`
filename=`basename "$file"`
#echo "dir is ""$dir"
#echo "$filename"

oldname=$filename
newname=
#
for sub in $filename
do
if [ $newname ]; then
newname=$newname"_"$sub
else
newname=$sub
fi
done

if [ "$newname" != "$oldname" ]; then #filename changed
if [ ! -f "$dir/$newname" ]; then #new file not exist
echo "rename file '$dir/$oldname' to '$dir/$newname'"
mv "$dir/$oldname" "$dir/$newname" #rename file
else #new file exist
echo "file exist: can not rename file '$dir/$oldname' to '$dir/$newname'"
fi
else
echo "file '$dir/$oldname' do not need rename."
fi
fi
done
}

#main begin
if [ $# -gt 0 ]; then
echo "All files which filename have whitesapce in folder '$1' and its subfolder will be rename."
else
echo "All files which filename have whitesapce in folder '.' and its subfolder will be rename."
fi

echo "Continue [y/n]?: \c"

read confirm
while [ "$confirm" != "y" ]
do
if [ "$confirm" = "n" ]; then
exit 0
fi

echo "Continue [y/n]?: \c"
read confirm
done

#do rename
if [ $# -gt 0 ]; then
rename "$1"
else
rename "."
fi
头像
xunknown
帖子: 22
注册时间: 2010-01-03 20:04
送出感谢: 0
接收感谢: 0

Re: 怎么把文件名中的空格全去掉

#8

帖子 xunknown » 2010-01-08 1:49

没注意到要改目录名,加上改目录名的功能,用下面代码:

#!/bin/sh
#使用bash做为默认shell

#create by Alpha @2010-01-08
#本程序的功能是遍历指定目录及其所有子目录,将所有子目录、文件名中的空格替换为下划线

#convert whitesapce to '_' in file name
rename_file()
{
for file in "$1"/*
do
if [ -d "$file" ]; then
rename_file "$file" #递归调用,遍历所有子目录
elif [ -f "$file" ]; then
dir=`dirname "$file"`
filename=`basename "$file"`
#echo "dir is ""$dir"
#echo "$filename"

#new file name
oldname=$filename
newname=
for sub in $filename
do
if [ $newname ]; then
newname=$newname"_"$sub
else
newname=$sub
fi
done

#rename file
if [ "$newname" != "$oldname" ]; then #file name changed
if [ ! -f "$dir/$newname" ]; then #file not exist, do rename
echo "rename file '$dir/$oldname' to '$dir/$newname'"
mv "$dir/$oldname" "$dir/$newname" #rename file
else #file exist
echo "file exist: can not rename file '$dir/$oldname' to '$dir/$newname'"
fi
else
echo "file '$dir/$oldname' do not need rename."
fi
fi
done
}

#convert whitesapce to '_' in dir name
rename_dir()
{
for file in "$1"/*
do
if [ ! -d "$file" ]; then
continue
fi

#new dir name
olddir=$file
newdir=
for sub in $file
do
if [ $newdir ]; then
newdir=$newdir"_"$sub
else
newdir=$sub
fi
done

#rename dir
if [ "$newdir" != "$olddir" ]; then #dir name changed
if [ ! -d "$newdir" -a ! -f "$newdir" ]; then #file not exist, do rename
echo "rename dir '$olddir' to '$newdir'"
mv "$olddir" "$newdir" #rename dir
else #file exist
echo "file exist: can not rename dir '$oledir' to '$newdir'"
newdir=$olddir #change var newdir for recurring
fi
else
echo "dir '$olddir' do not need rename."
newdir=$olddir #change var newdir for recurring
fi
rename_dir "$newdir" #递归
done
}

#main begin
if [ $# -gt 0 ]; then
echo "All files which filename have whitesapce in folder '$1' will be rename."
else
echo "All files which filename have whitesapce in folder '.' will be rename."
fi

echo "Continue [y/n]?: \c"

read confirm
while [ "$confirm" != "y" ]
do
if [ "$confirm" = "n" ]; then
exit 0
fi

echo "Continue [y/n]?: \c"
read confirm
done

#do rename
if [ $# -gt 0 ]; then
rename_file "$1"
rename_dir "$1"
else
rename_file "."
rename_dir "."
fi

<<<<<<<<----------以上是最新的-------------


xunknown 写了:用下面在脚本,经过测试:

#!/bin/sh
#使用bash做为默认shell

#create by Alpha @2010-01-08
#本程序的功能是遍历指定目录及其所有子目录,将所有文件名(目录除外)中的空格替换为下划线,

#convert whitesapce to '_' in filename
rename()
{
for file in "$1"/*
do
if [ -d "$file" ]; then
rename "$file" #递归调用,遍历所有子目录
elif [ -f "$file" ]; then
dir=`dirname "$file"`
filename=`basename "$file"`
#echo "dir is ""$dir"
#echo "$filename"

oldname=$filename
newname=
#
for sub in $filename
do
if [ $newname ]; then
newname=$newname"_"$sub
else
newname=$sub
fi
done

if [ "$newname" != "$oldname" ]; then #filename changed
if [ ! -f "$dir/$newname" ]; then #new file not exist
echo "rename file '$dir/$oldname' to '$dir/$newname'"
mv "$dir/$oldname" "$dir/$newname" #rename file
else #new file exist
echo "file exist: can not rename file '$dir/$oldname' to '$dir/$newname'"
fi
else
echo "file '$dir/$oldname' do not need rename."
fi
fi
done
}

#main begin
if [ $# -gt 0 ]; then
echo "All files which filename have whitesapce in folder '$1' and its subfolder will be rename."
else
echo "All files which filename have whitesapce in folder '.' and its subfolder will be rename."
fi

echo "Continue [y/n]?: \c"

read confirm
while [ "$confirm" != "y" ]
do
if [ "$confirm" = "n" ]; then
exit 0
fi

echo "Continue [y/n]?: \c"
read confirm
done

#do rename
if [ $# -gt 0 ]; then
rename "$1"
else
rename "."
fi
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

Re: 怎么把文件名中的空格全去掉

#9

帖子 eexpress » 2010-01-08 8:39

?????????这么复杂??
rename 's/\ //g' * 不行吗?
● 鸣学
DerekTan
帖子: 33
注册时间: 2007-05-22 10:48
送出感谢: 0
接收感谢: 0
联系:

Re: 怎么把文件名中的空格全去掉

#10

帖子 DerekTan » 2010-01-08 10:45

eexpress 写了:?????????这么复杂??
rename 's/\ //g' * 不行吗?
光靠这行貌似不行~
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

Re: 怎么把文件名中的空格全去掉

#11

帖子 eexpress » 2010-01-08 10:51

说下。为什么不行。
find可带-exec bash -c '' \;
那''里面可以调用rename xxxx {}的。
怎么样,都是一行代码
● 鸣学
DerekTan
帖子: 33
注册时间: 2007-05-22 10:48
送出感谢: 0
接收感谢: 0
联系:

Re: 怎么把文件名中的空格全去掉

#12

帖子 DerekTan » 2010-01-08 10:59

谢谢xunknown的帮助

试了一下你的脚本,好像子目录的名字没有全部改过来,你看看是不是哪里漏了?仍然很感谢你,你的脚本也给我带来了启发 :em01

自己写了一个,

代码: 全选

#!/bin/bash

modifyname()
{
    if [ -d "$1" ]  #directory
    then
        for files in "$1"/*
        do
            modifyname "$files"
        done
    fi
    bname=`basename "$1"` 
        echo $bname | grep -q " " #chech if contains blank
        if [ $? -eq 0 ]
    then
        dname=`dirname "$1"`
        newname=$dname/${bname// /_}
        mv -v "$1" "$newname"
    fi
}

[ -e "$1" ] || { echo "$1 does not exist"; exit 1; }

modifyname "$1"
exit 0
DerekTan
帖子: 33
注册时间: 2007-05-22 10:48
送出感谢: 0
接收感谢: 0
联系:

Re: 怎么把文件名中的空格全去掉

#13

帖子 DerekTan » 2010-01-08 11:20

eexpress 写了:说下。为什么不行。
find可带-exec bash -c '' \;
那''里面可以调用rename xxxx {}的。
怎么样,都是一行代码
谢谢小e~~
比如原本有a a/b b b/c c c c
find出来的效果是这样的
./a a
./a a/b b b
./a a/b b b/c c c c
这样先把a a的名字给改了以后,./a a/b b b就不存在了吧?所以rename的时候会出错?

然后我就改成了这样:
find . -name "*" | tac | xargs -I{} rename ' ' '_' {}
还是不行——我测试的时候建了几重文件夹,胡乱放了几个文件,反正有一些没有改过来

另外,那个 rename 's/\ //g' {} 我不太懂……rename不是要三个参数的吗?这里面……

谢谢ee:)
头像
openware
帖子: 173
注册时间: 2009-02-22 14:15
送出感谢: 0
接收感谢: 0
联系:

Re: 怎么把文件名中的空格全去掉

#14

帖子 openware » 2010-01-08 13:31

恩,ee这招比较帅,抵得上万行代码。
Desire Freedom, Love Beauty, Keep Hacking。
DerekTan
帖子: 33
注册时间: 2007-05-22 10:48
送出感谢: 0
接收感谢: 0
联系:

Re: 怎么把文件名中的空格全去掉

#15

帖子 DerekTan » 2010-01-08 13:48

openware 写了:恩,ee这招比较帅,抵得上万行代码。
囧。。。我用ee的方法不行啊,是我没有领会到吗?你帮我讲讲撒~~多谢啦!
回复

回到 “Shell脚本”