Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1848647
  • 博文数量: 293
  • 博客积分: 10127
  • 博客等级: 上将
  • 技术积分: 3029
  • 用 户 组: 普通用户
  • 注册时间: 2010-08-12 19:05
文章分类

全部博文(293)

文章存档

2011年(11)

2010年(282)

我的朋友

分类: LINUX

2010-12-29 22:19:25

需求:某个文件夹下所有的文件名字里的大写字母改成小写字母。
解决:
for file in `ls | grep '[A-Z]'`
do
str=`echo $file|tr 'A-Z' 'a-z'`
mv $file $str
done
1)ls | grep '[A-Z]' :ls 出所有含有大写字母的文件
2)for file in `command` :for 循环
3)echo AVdxFV | tr 'A-Z' 'a-z' : 把'AVdxFV' 中所有的大写换成小写字母; tr :translate的意思,具体看help
 
 
 
 
 
 
 
 
最近复习shell编程,搞了个递归实现批量转换文件名大小写的脚本,放在这里做个备份。具体用法:
Usage: ./switchcase.sh -direct  item1 item2 ...
direct: u -- to upcase\(default\), l -- to lowcase
item1 item2 ...: dirs you want\(default is current dir.\)

#!/bin/bash

#批量转换文件名大小写

#by YangJie 2008-08-19


traversal()
{
  COUNT=0
  for curitem in $*
  do
    if [ -d $curitem ]
    then
          cd $curitem
# echo "curitem is $curitem, currrent dir is $PWD"

          traversal `ls $PWD`
          for item in `ls -F $PWD | grep \/`
#找当前目录下所有的目录

          do
              echo -e "\033[1;36;40m[ $curitem:\033[1;34;40m Moving `basename $item` to `basename $item | $direct` ...\033[1;36;40m]\033[0m"
              mv -f `basename $item` `basename $item | $direct`
          done
          cd ..
     else
          echo -e "\033[1;36;40m[ `basename $PWD`:\033[0mMoving $curitem to `basename $curitem | $direct` ... \033[1;36;40m]\033[0m"
          mv -f $curitem `basename $curitem | $direct`
     fi


  done
}

args=$
#; #参数个数──$#


[ $args -lt 1 ] && { echo "Usage: $0 -direct item1 item2 ..."; \
                echo "direct: u -- to upcase\(default\), l -- to lowcase";\
                echo "item1 item2 ...: dirs you want\(default is current dir.\)";\
                exit 1; }
direct="tr [a-z] [A-Z]" ;
if [ X$1 = X'-u' ]
then
 shift
fi
#去掉参数用shift

if [ X$1 = X'-l' ]
then
  direct="tr [A-Z] [a-z]"
  shift
fi
#echo "item is $item,args is $args"

#批量更改

traversal $*
#最后更改参数列表里面的目录

for it in $*
do
  mv -f `basename $it` `basename $it | $direct`
done

exit 0;
# (End)

 
 
 
 
 
文件名转化大小写
2004-04-23 15:18 pm
来自:Linux文档
现载:
地址:无名

不用这么麻烦了,这是个比较经典的shell问题,正是shell发挥作用的时候
先提供两个方法:
1、
for uppercase in `ls`
do
for lowercase in `ls $uppercase|tr [A-Z] [a-z]`
do
mv $uppercase $lowercase 2>/dev/null
done
done

2、
typeset -u Lcase
for Ucase in `ls`
do
Lcase=$Ucase
mv $Ucase $Lcase
done

请大家完善并补充

for file in `ls`
do
mv $file `echo $file|tr "[A-Z]" "[a-z]"`
done

用awk也行 :)
#!/bin/sh
for I in `ls` ;
do
C=$(echo $I|awk '{print toupper($I)}')
mv $I $C
done

for i in *
do
a=`echo $i |tr '[a-z]' '[A-Z]'`
cp $i $a
echo $a
rm -i $a
done



我的当前目录及其n级深度的子目录都是大写,我想改成小写。我用find . -exec file.sh {} ; 怎么每次都只能改一级的深度?非得用for 和cd/cd..才可以完成吗?



find . -exec ...这样的命令肯定是递归搜索了(即深入n层目录)了,大半是你的file.sh有问题,无法处理带有目录的文件名,如:./a/file.txt文件在你的的脚本处理下,被处理成:mv ./a/file.txt ./A/FILE.TXT, ./A目录不存在当然mv不成功了。

应该是在file.sh上出的问题,我是这么简单的做的:
#!/bin/sh
new=`echo $1|tr "[a-z]" "[A-Z]"`
mv $1 $new

这样的shell是基于find对深层目录处理时候是先从最深层处理的,现在看来find是从当前开始处理再至最深层的。
那这样大小写转换的shell又该怎样写呢?


拆分后再转换
#!/bin/sh
dn=`dirname $1`
fn=`basename $1`
newfn=`echo $fn|tr "[a-z]" "[A-Z]"`
mv $1 $dn/$newfn

测试没通过。

n=`dirname $1`
newdn=`echo $dn|tr "[a-z]" "[A-Z]"`
fn=`basename $1`
newfn=`echo $fn|tr "[a-z]" "[A-Z]"`
f1=$newdn/$fn
f2=$newdn/$newfn

if [ $f1 != $f2 ]
then
echo "$f1 $f2"
mv $f1 $f2
fi

这个可以了。不过执行的时候这sh不能在被转化的目录中。
应该这样:find . -exec ../mysh.sh {} ;





下面引用由samhoo在 2002/10/24 03:33pm 发表的内容:
dn=`dirname $1`
newdn=`echo $dn|tr "" ""`
fn=`basename $1`
newfn=`echo $fn|tr "" ""`
...



呵呵,这个肯定也不行,不知道有没有人测试过?!
原因是:你改过了目录的名字,所以$f1的目录$newdn是不存在的;还有如果有空目录出现,程序也是处理不了的。
只有每次处理都重新读一次目录才可以,信乎?!

俺测了,干活啊

就是要把脚本放在所检验目录子外




下面引用由smileniu在 2002/12/17 02:51pm 发表的内容:
呵呵,这个肯定也不行,不知道有没有人测试过?!
原因是:你改过了目录的名字,所以$f1的目录$newdn是不存在的;还有如果有空目录出现,程序也是处理不了的。
只有每次处理都重新读一次目录才可以,信乎?!




分析的很对!一旦发生路径名改动,后面的都用不成了~~~

可以改成这样就行了,

代码:


FILES=`find $1 | sort -r`

for i in $FILES; do
DIR=`dirname $i`
BAS=`basename $i | tr '[a-z]' '[A-Z]'`
bas=`echo $BAS | tr '[A-Z]' '[a-z]'`

mv $DIR/$BAS $DIR/$bas
done



(不知为什么,后半部分居然没贴上,超出本页最大长度啦?)

如果适当扩展一下,改成可以带参数,大写变小写,或者小写变大写,完整的如下

代码:


#!/bin/sh

############################################################
# this script will change file name recursively with option
# -u: locase to upcase
# -l: upcase to locase
############################################################

hint () {
echo " Usage: $0 [-l|-u] DIR1 [DIR2 DIR3...]
-l to lowcase
-u to upcase"
exit 1
}

if test $# -lt 2; then
echo "Too few arguments."
hint
fi

while [ "$1" ]; do
case $1 in
-l) ACTION="lo"
shift 1
;;
-u) ACTION="up"
shift 1
;;
*) if test -d $1; then
DIR="$DIR $1"
else
echo "no such directory --- $1"
hint
fi
shift
;;
esac
done

# echo $ACTION
# echo $DIR


FOUND=`find $DIR | sort -r`

for i in $FOUND; do
DN=`dirname $i`
BS=`basename $i`
loBS=`echo $BS | tr '[A-Z]' '[a-z]'`
upBS=`echo $BS | tr '[a-z]' '[A-Z]'`

NAME1=$DN/$BS

if [ "$ACTION" = "lo" ]; then
NAME2=$DN/$loBS
elif [ "$ACTION" = "up" ]; then
NAME2=$DN/$upBS
fi

if [ "$NAME1" = "$NAME2" ]; then
echo "****: $NAME1 ---x--- $NAME2 identical!"
else
echo "- renaming $NAME1 --> $NAME2"
mv $NAME1 $NAME2
fi
done

是啊~

其实仔细看了一下楼上的帖子,发现问题的所在就是 find 得到结果并不能直接拿来处理,因为它是自上而下的,而目录一旦改名,子目录就全抓瞎了。而经过排序后(先处理最深的目录,由里向外)就能用了。

然后稍作修改,并加上一些参数,使之有一定的实用性。
 
 
 
 
#!/bin/bash
dir="./trtests";    
files=`find$dir-typef`;
foriin$files    
do    
dir_name=`dirname$i`;
ori_filename=`basename$i`;
new_filename=`echo$ori_filename|tr[:lower:][:upper:]`>/dev/null;    
mv$dir_name/$ori_filename$dir_name/$new_filename
done
tr[:lower:][:upper:]也可以换成tr a-z A-Z
以上的代码主要是实现将文件夹trtests中的小写文件名转换成大写文件名
阅读(15135) | 评论(2) | 转发(0) |
0

上一篇:DS5020问题点滴

下一篇:AIX 安装字符集

给主人留下些什么吧!~~

prayer1632013-11-15 17:07:21

最后的例子怎么空格没有了,还得调

chinaunix网友2011-01-02 11:54:50

很好的, 收藏了 推荐一个博客,提供很多免费软件编程电子书下载: http://free-ebooks.appspot.com