代码之家  ›  专栏  ›  技术社区  ›  agnul

如何从bash中的文件中读取文件名列表?

  •  31
  • agnul  · 技术社区  · 15 年前

    我正在尝试编写一个bash脚本,它将处理一个文件列表,这些文件的名称每行存储在一个输入文件中,类似于

    find . -type f -mtime +15 > /tmp/filelist.txt
    for F in $(cat /tmp/filelist.txt) ; do
      ...
    done;
    

    我的问题是filelist.txt中的文件名可能包含空格,因此上面的截图将扩展该行。

    my text file.txt
    

    三个不同的文件名, my , text file.txt .我怎样才能解决这个问题?

    7 回复  |  直到 15 年前
        1
  •  40
  •   Douglas Leeder    15 年前

    使用 read :

    while read F  ; do
            echo $F
    done </tmp/filelist.txt
    

    或者使用ifs更改shell分隔列表的方式:

    OLDIFS=$IFS
    IFS="
    "
    for F in $(cat /tmp/filelist.txt) ; do
      echo $F
    done
    IFS=$OLDIFS
    

    或者(如@tangens建议的那样),将循环体转换为单独的脚本,然后使用 find 的-exec选项,用于直接找到的每个文件的if。

        2
  •  7
  •   Dennis Williamson    15 年前

    您可以在不使用临时文件的情况下使用进程替换来执行此操作:

    while read F
    do
      ...
    done < <(find . -type f -mtime +15)
    
        3
  •  3
  •   DVK    15 年前

    阅读时使用

    echo $FILE | while read line
    do
    echo $line
    done
    

    你可以做重定向而不是回声

        4
  •  2
  •   tangens    15 年前

    你可以用 -exec 参数 find 直接使用文件名:

    find . -type f -mtime +15 -exec <your command here> {} \;
    

    这个 {} 是文件名的占位符。

        5
  •  1
  •   ghostdog74    15 年前

    将find命令直接发送到while read循环

    find . -type f -mtime +15 | while read -r line
    do
       printf "do something with $line\n"
    done
    
        6
  •  0
  •   konung    15 年前

    我不是bash专家(我通常用ruby或python编写脚本以实现跨平台),但在处理之前,我会使用regex expration来转义每行中的空格。

    Bash正则表达式: http://www.linuxjournal.com/node/1006996

    在Ruby中的类似情况下(处理一个csv文件,并在使用之前清理每一行):

    File.foreach(csv_file_name) do |line| 
        clean_line = line.gsub(/( )/, '\ ') 
        #this finds the space in your file name and escapes it    
        #do more stuff here
    end  
    
        7
  •  -1
  •   qid    15 年前

    我相信您可以完全跳过临时文件,直接迭代find的结果,即:

    for F in $(find . -type f -mtime +15) ; do
      ...
    done;
    

    不能保证我的语法是正确的,但我很确定这个概念是有效的。

    编辑:如果您确实需要使用文件名列表来处理文件,并且不能像上面所做的那样简单地组合命令,那么您可以更改 IFS 变量——它代表内部字段分隔符——用于更改bash确定字段的方式。默认情况下,它设置为空白,因此换行符、空格或制表符将开始一个新字段。如果将其设置为只包含换行符,那么可以像以前那样迭代文件。