Ubu*_*ser 48 bash scripts 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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
但是FILE变量只存储路径的第一部分./F1/F1-2013-03-19,然后是下一部分160413.csv。
我尝试使用readwhile 循环,
while read `find . -type f -iname '*.*'`; do ls $REPLY; done
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误
bash: read: `./F1/F1-2013-03-19': not a valid identifier
Run Code Online (Sandbox Code Playgroud)
任何人都可以建议另一种方式吗?
更新
正如下面的答案中所建议的,我更新了脚本
#!/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
Run Code Online (Sandbox Code Playgroud)
我得到的输出是
./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
Run Code Online (Sandbox Code Playgroud)
Tho*_*hor 55
在这里使用forwithfind是错误的方法,例如参见这篇关于您正在打开的蠕虫罐头的文章。
推荐的方法是使用find,while并read描述在这里。下面是一个应该适合你的例子:
find . -type f -name '*.*' -print0 |
while IFS= read -r -d '' file; do
printf '%s\n' "$file"
done
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以用空 ( \0) 字符分隔文件名,这意味着空格和其他特殊字符的变化不会导致问题。
为了使用find找到的文件更新存档,您可以将其输出直接传递给tar:
find . -type f -name '*.*' -printf '%p\0' |
tar --null -uf archive.tar -T -
Run Code Online (Sandbox Code Playgroud)
请注意,您不必区分存档是否存在,tar会明智地处理它。还要注意使用-printfhere 以避免./在存档中包含该位。
kir*_*iri 18
尝试for像这样引用循环:
for FILE in "`find . -type f -name '*.*'`" # note the quotation marks
Run Code Online (Sandbox Code Playgroud)
没有引号,bash 根本不能很好地处理空格和换行符 ( \n)...
也尝试设置
IFS=$'\n'
Run Code Online (Sandbox Code Playgroud)
小智 17
这有效并且更简单:
find . -name '<pattern>' | while read LINE; do echo "$LINE" ; done
Run Code Online (Sandbox Code Playgroud)
此答案归功于 Rupa ( https://github.com/rupa/z )。
| 归档时间: |
|
| 查看次数: |
109115 次 |
| 最近记录: |