我的目标是在某些 $devices 上找到 $files 并将它们保存到一个或多个文件夹中,这些文件夹的名称与每个文件的时间戳相对应。为了获取时间戳,我想使用 stat。
与 echo "$files" 相比,stat 不会单独处理每个文件。相反,当我使用“”时,它似乎会立即处理所有文件。
您对如何改进引用有什么建议,或者对如何使 stat 能够做我想做的事情有任何其他提示吗?非常感谢您的帮助。
#!/bin/bash
for devices in "$(ls /media/*/)";
do
for files in "$(find /media/*/$devices -iname *.jpg)";
do
echo "$files" # prints all files in separate lines
stat "$files" # seems to process all files at once
stat $files # splits file paths at spaces
done
done
答案1
问题不在于循环stat
中的源数据,而在于循环中的源数据for
;因为您将其全部用引号引起来,所以它成为一个长的单一实体。
要解决此问题,请删除它周围的引号,因此:
for files in $(find /media/*/$devices -iname "*.jpg");
只要所有文件或路径都没有空格,它就可以工作。但是有一个更优雅的解决方案,可以处理空格,甚至奇怪的文件名(例如包含引号或换行符的文件名):
while IFS= read -r -d '' file; do
# operations on each "$file" here
done < <(find /media/*/$devices -type f -iname *.jpg -print0)
答案2
不解析输出ls
。您无法区分由 引入的换行符ls
和文件名中的换行符。也同样如此find
。
for devices in $(ls /media/*/)
只是一种复杂的、破碎的写作方式for devices in /media/*/*
。而不是for files in $(find …); do …; done
使用find … -exec …
.
这里不需要两个循环,因为您只是枚举文件以便稍后使用完整的文件集。你的脚本很简单
find /media/*/* -iname '*.jpg' -exec stat {} +
有关更多信息,请参阅为什么我的 shell 脚本会因为空格或其他特殊字符而卡住?