Chinaunix

标题: 递归把一个目录包括子目录中的所有文件转换成unix格式 [打印本页]

作者: ytsmtipe    时间: 2009-06-09 11:51
标题: 递归把一个目录包括子目录中的所有文件转换成unix格式
各位,兄弟最近实现了一个可以递归把一个目录包括子目录中的所有文件转换成unix格式文件的shell script,但是如果一个文件名中间有空格(比如叫"how to do.txt")就会停止工作,我不知道如何解决,希望大侠们帮忙解决一下子,谢谢!
代码如下:

#!/bin/bash

#This script convert all the files within $1 directory to DOS format.

#bug:can't convert files if the filename contains spaces.

#                                -leiyu.


recursive_dos2unix()
{
        for x in $(ls)
        do
                if [ -f "$x" ]
                then
                        chmod a+w ./"$x"
                        dos2unix ./"$x"
                        chmod a-w ./"$x"

                elif [ -L "$x" ]
                then
                        echo "this is a link"
                else
                        cd "$x"

                        if [ "$?" != "0" ]
                        then
                            echo "cd failed, exit now."
                            exit 1
                        fi

                        pwd
                        recursive_dos2unix
                        cd ..
                fi
        done
}

echo "Start convert"
cd $1
recursive_dos2unix
echo "end of convert"


[ 本帖最后由 ytsmtipe 于 2009-6-9 11:55 编辑 ]
作者: lululau    时间: 2009-06-09 12:02
for x in "$(ls)"
作者: merlin852    时间: 2009-06-09 12:06
find . -type f -exec dos2unix {}  \;
作者: ywlscpl    时间: 2009-06-09 12:11
find . -type f -exec dos2unix {} \;
作者: ywlscpl    时间: 2009-06-09 12:12
原来有人已经发了
作者: mixednuts    时间: 2009-06-09 12:12
第一次使用这个变量时完成:

x=${x//\ /\\\ }                   //目的是把空格换成"\ "

[ 本帖最后由 mixednuts 于 2009-6-9 12:18 编辑 ]
作者: ytsmtipe    时间: 2009-06-09 13:10
标题: 回复 #2 lululau 和mixednuts 的帖子
刚刚试验了一下子,两位提出的方法,好像没有起作用。
作者: ywlscpl    时间: 2009-06-09 13:19
标题: 回复 #7 ytsmtipe 的帖子
for x in $(ls)
ls的输出,shell会以IFS分割然后进行循环

加引号的话ls的内容会作为一个整体,只循环一次

[ 本帖最后由 ywlscpl 于 2009-6-9 13:27 编辑 ]
作者: lululau    时间: 2009-06-09 13:32
原帖由 ywlscpl 于 2009-6-9 13:19 发表
for x in $(ls)
ls的输出,shell会以IFS分割然后进行循环

加引号的话ls的内容会作为一个整体,只循环一次



我的想法和你一样

可是有一种情况很奇怪:

  1. [root@0609-0090 ~/cafe/sh]# ls | cat
  2. 3-3.sh
  3. abc sa
  4. at--help.txt
  5. chars
  6. iii
  7. puzzle.sh
  8. test-suspend.sh
  9. [root@0609-0090 ~/cafe/sh]# for i in "$(ls)"; do echo $i; done
  10. 3-3.sh abc sa at--help.txt chars iii puzzle.sh test-suspend.sh
  11. [root@0609-0090 ~/cafe/sh]# for i in "$(ls)"; do echo "$i"; done
  12. 3-3.sh
  13. abc sa
  14. at--help.txt
  15. chars
  16. iii
  17. puzzle.sh
  18. test-suspend.sh
  19. [root@0609-0090 ~/cafe/sh]# uname -a
  20. CYGWIN_NT-5.1 0609-0090 1.5.25(0.156/4/2) 2008-06-12 19:34 i686 Cygwin
  21. [root@0609-0090 ~/cafe/sh]# echo $SHELL
  22. /bin/bash
  23. [root@0609-0090 ~/cafe/sh]#

复制代码

作者: mixednuts    时间: 2009-06-09 13:36
ls |sed 's/\ /\\\ /g'| xargs dos2unix
作者: ywlscpl    时间: 2009-06-09 13:38
标题: 回复 #9 lululau 的帖子
应该还是一次循环,不过也还是疑惑这个输出效果
  1. [root@Mylinux tmp]# for i in "$(ls)"; do echo "#$i#"; done
  2. #aa
  3. a b c
  4. file
  5. mysh
  6. oo
  7. test#
复制代码

作者: ly5066113    时间: 2009-06-09 13:40
标题: 回复 #11 ywlscpl 的帖子
echo $(ls)
echo "$(ls)"
作者: lululau    时间: 2009-06-09 13:45
标题: 回复 #12 ly5066113 的帖子
呵呵,明白啦,谢谢
作者: mixednuts    时间: 2009-06-09 13:51
for x in $(ls | sed 's/\ /\\/g' )
        do
                echo $x
                x=${x/\\/\\\ }
作者: ywlscpl    时间: 2009-06-09 13:54
标题: 回复 #13 lululau 的帖子
翻了下十三问,还是没明白,帮忙解释解释吧
echo $(ls)和 echo "$(ls)"的输出效果为何有区别
作者: 我是DBA    时间: 2009-06-09 13:58
标题: 回复 #15 ywlscpl 的帖子
这个是因为echo的原因
作者: ywlscpl    时间: 2009-06-09 14:01
标题: 回复 #16 我是DBA 的帖子
觉得可能跟这个有关,但没想通
* soft quote: " " (雙引號),在 soft quoe 中大部份 meta 都會被關閉,但某些則保留(如 $ )。(註二)

作者: lululau    时间: 2009-06-09 14:03
因为echo $(ls),把换行符换成了空格(因为换行符是IFS)
echo "$(ls)":双引号里面的的不进行字段拆分,自然也就没有换行符到空格的转换啦

其实我说明白了,是说明白了,原来那个循环只循环了一次
作者: springwind426    时间: 2009-06-09 14:13

  1. for x in $(ls)
  2. do

  3. 修改成

  4. for x in *
  5. do
  6.    [ -e "$f" ] || continue

复制代码

[ 本帖最后由 springwind426 于 2009-6-9 14:21 编辑 ]
作者: ywlscpl    时间: 2009-06-09 14:14
标题: 回复 #18 lululau 的帖子
ls的输出本身就没有换行符啊(内容在一行之内)
  1. [root@Mylinux tmp]# ls
  2. aa  a b c  file  MiscRunLog_Report.tmp  mysh  oo  Stat_Tmp  test
  3. [root@Mylinux tmp]#
复制代码

作者: lululau    时间: 2009-06-09 14:21
那是因为ls会判断输出连接到的文件类型,如果输出到终端,会根据终端的几何特征以不同的格式输出。如果连接到普通文件或者管道,或者是在命令替换中输出,那么就是每个文件名一行了。你可以试一下 ls | cat,或者直接ls | od -Ad -tc 看看有没有\n
作者: ywlscpl    时间: 2009-06-09 14:27
标题: 回复 #21 lululau 的帖子
明白了,十分感谢
作者: blackold    时间: 2009-06-09 14:38
晕哦。
作者: ly5066113    时间: 2009-06-09 14:49
标题: 回复 #21 lululau 的帖子
这个和ls无关哦,是 `` 或 $() 的问题。

  1.    Command Substitution
  2.        Command substitution allows the output of a command to replace the com-
  3.        mand name.  There are two forms:

  4.               $(command)
  5.        or
  6.               `command`

  7.        Bash performs the expansion by executing command and replacing the com-
  8.        mand  substitution  with  the  standard output of the command, with any
  9.        trailing newlines deleted.  Embedded newlines are not deleted, but they
  10.        may  be  removed during word splitting.  The command substitution $(cat
  11.        file) can be replaced by the equivalent but faster $(< file).

  12.        When the old-style backquote form of substitution  is  used,  backslash
  13.        retains  its  literal  meaning except when followed by $, `, or \.  The
  14.        first backquote not preceded by a backslash terminates the command sub-
  15.        stitution.   When using the $(command) form, all characters between the
  16.        parentheses make up the command; none are treated specially.

  17.        Command substitutions may be nested.  To nest when using the backquoted
  18.        form, escape the inner backquotes with backslashes.

  19.        If  the  substitution  appears within double quotes, word splitting and
  20.        pathname expansion are not performed on the results.
复制代码

作者: blackold    时间: 2009-06-09 14:49
标题: 回复 #1 ytsmtipe 的帖子
try:
#!/bin/bash
IFS=$'\n'
...

作者: blackold    时间: 2009-06-09 14:53
word splitting
作者: lululau    时间: 2009-06-09 15:06
标题: 回复 #24 ly5066113 的帖子
这个我明白,暮木同学的疑问是为什么ls输出的结果本来是没有\n的,为什么echo "$(ls)"就有了\n




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2