使用Bash脚本,我想通过使用for循环移动文件列表,而不是使用while循环(用于测试目的)。任何人都可以向我解释为什么mv总是充当文件重命名而不是文件移动在这个for循环下?如何修复它以移动文件列表?
以下作品:
for file in "/Volumes/HDD1/001.jpg" "/Volumes/HDD1/002.jpg"
do
mv "$file" "/Volumes/HDD2/"
done
更新#1:
但是,假设我有一个sample_pathname.txt
cat sample_pathname.txt
"/Volumes/HDD1/001.jpg" "/Volumes/HDD1/002.jpg"
为什么以下for循环不起作用?
array=$(cat sample_path2.txt)
for file in "${array[@]}"
do
mv "$file" "/Volumes/HDD2/"
done
感谢。
系统:OS X
Bash版本:3.2.53(1)
答案 0 :(得分:2)
cat sample_pathname.txt
"/Volumes/HDD1/001.jpg" "/Volumes/HDD1/002.jpg"
这里的引号是问题所在。除非你需要处理带有换行符的文件名,否则简单而标准的方法是每行列出一个文件名,没有引号或其他元信息。
vbvntv$ cat sample_pathname_fixed.txt
/Volumes/HDD1/001.jpg
/Volumes/HDD1/002.jpg
vbvntv$ while read -r file; do
> mv "$file" "/Volumes/HDD2/"
> done <sample_pathname_fixed.txt
事实上,你甚至可以
xargs mv -t /Volumes/HDD2 <sample_pathname_fixed.txt
(在某种程度上取决于你的xargs
是如何脑死亡的。)
答案 1 :(得分:2)
您的示例中使用的语法不会创建数组...它只是将文件内容存储在名为array的变量中。
IFS = $&#39; \ n&#39; array = $(cat sample_path2.txt)
如果你有一个包含文件名的文本文件(每个文件在最后一行上最简单),你可以将它加载到一个数组中并按如下方式迭代它。注意使用$(&lt; file)作为cat的更好替代方法,并使用括号将内容初始化为数组。文件的每一行对应一个索引。
array=($(< file_list.txt ))
for file in "${array[@]}"; do
mv "$file" "/absolute/path"
done
更新:如果帖子顶部的命令不起作用,您的IFS可能未正确设置。我更新了它以反映这一点。此外,还有一些其他可靠的方法可以从文件初始化数组。但是就像你提到的那样,如果你只是直接将文件传递给while循环,你可能不需要它。
这是一个内置在Bash 4+中的shell和mapfile的同义词。如果它可用,这种方法很有效。
readarray -t array < file
&#39;阅读&#39;命令还可以为您初始化数组:
IFS=$'\n' read -d '' -r -a array < file
答案 2 :(得分:1)
使用它:
for file in "/Volumes/HDD1/001.jpg" "/Volumes/HDD1/002.jpg"
do
f=$(basename $file)
mv "$file" "/Volumes/HDD2/$f"
done