文件名带有空格,会中断 for 循环和 find 命令

文件名带有空格,会中断 for 循环和 find 命令

我有一个脚本,用于搜索多个子文件夹和存档中的所有文件以进行 tar。我的脚本是

for FILE in `find . -type f  -name '*.*'`
  do
if [[ ! -f archive.tar ]]; then

  tar -cpf archive.tar $FILE
else 
  tar -upf archive.tar $FILE 
fi
done

find 命令给出以下输出

find . -type f  -iname '*.*'
./F1/F1-2013-03-19 160413.csv
./F1/F1-2013-03-19 164411.csv
./F1-FAILED/F2/F1-2013-03-19 154412.csv
./F1-FAILED/F3/F1-2011-10-02 212910.csv
./F1-ARCHIVE/F1-2012-06-30 004408.csv
./F1-ARCHIVE/F1-2012-05-08 190408.csv

文件变量仅存储路径的第一部分./F1/F1-2013-03-19然后是下一部分160413.csv

我尝试使用readwhile 循环,

while read `find . -type f  -iname '*.*'`;   do ls $REPLY; done

但我收到以下错误

bash: read: `./F1/F1-2013-03-19': not a valid identifier

有人可以建议其他方法吗?

更新

正如下面的答案所建议的,我更新了脚本

#!/bin/bash

INPUT_DIR=/usr/local/F1
cd $INPUT_DIR
for FILE in "$(find  . -type f -iname '*.*')"
do
archive=archive.tar

        if [ -f $archive ]; then
        tar uvf $archive "$FILE"
        else
        tar -cvf $archive "$FILE"
        fi
done

我得到的输出是

./test.sh
tar: ./F1/F1-2013-03-19 160413.csv\n./F1/F1-2013-03-19 164411.csv\n./F1/F1-2013-03-19 153413.csv\n./F1/F1-2013-03-19 154412.csv\n./F1/F1-2012-09-10 113409.csv\n./F1/F1-2013-03-19 152411.csv\n./.tar\n./F1-FAILED/F3/F1-2013-03-19 154412.csv\n./F1-FAILED/F3/F1-2013-03-19 170411.csv\n./F1-FAILED/F3/F1-2012-09-10 113409.csv\n./F1-FAILED/F2/F1-2011-10-03 113911.csv\n./F1-FAILED/F2/F1-2011-10-02 165908.csv\n./F1-FAILED/F2/F1-2011-10-02 212910.csv\n./F1-ARCHIVE/F1-2012-06-30 004408.csv\n./F1-ARCHIVE/F1-2011-08-17 133905.csv\n./F1-ARCHIVE/F1-2012-10-21 154410.csv\n./F1-ARCHIVE/F1-2012-05-08 190408.csv: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

答案1

在这里使用forwithfind是错误的方法,例如这篇文章关于你正在打开的潘多拉魔盒。

建议的方法是使用findwhile如下read所述这里。下面是一个适合您的示例:

find . -type f -name '*.*' -print0 | 
while IFS= read -r -d '' file; do
    printf '%s\n' "$file"
done

这样,您就可以用空字符(\0)分隔文件名,这意味着空格和其他特殊字符的变化不会引起问题。

为了使用find定位的文件更新档案,您可以将其输出直接传递给tar

find . -type f -name '*.*' -printf '%p\0' | 
tar --null -uf archive.tar -T -

请注意,您不必区分档案是否存在,tar将合理处理。还请注意此处的使用,-printf以避免将./位包含在档案中。

答案2

这有效并且更简单:

find . -name '<pattern>' | while read LINE; do echo "$LINE" ; done

感谢 Rupa (https://github.com/rupa/z) 来回答这个问题。

答案3

尝试for像这样引用循环:

for FILE in "`find . -type f  -name '*.*'`"   # note the quotation marks

\n如果没有引号,bash根本不能很好地处理空格和换行符( )......

还可以尝试设置

IFS=$'\n'

答案4

我做了类似的事情来查找可能包含空格的文件。

IFS=$'\n'
for FILE in `/usr/bin/find $DST/shared -name *.nsf | grep -v bookmark.nsf | grep -v names.nsf`; do
    file $FILE | tee -a $LOG
done

非常有效 :)

相关内容