我有一个脚本,用于搜索多个子文件夹和存档中的所有文件以进行 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。
我尝试使用read
while 循环,
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
在这里使用for
withfind
是错误的方法,例如这篇文章关于你正在打开的潘多拉魔盒。
建议的方法是使用find
,while
如下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
非常有效 :)