我有一个文件列表,我想将其从一个文件夹移动到A
另一个文件夹B
,但我不想手动执行此操作。有没有更简单的方法来循环列表并移动该列表中的每个文件?
答案1
您可以使用rsync
移动它们,假设您的文件列表是每行一个文件名。
rsync -av --remove-source-files --files-from filelist.txt sourceDir/ targetDir/
如果您的文件是绝对名称(即名称以 开头/
),则sourceDir
应该是/
.否则它应该是相对名称的根。
例子
$ mkdir src dst
touch src/{one,two,three}
$ cat >filelist.txt <<EOF
one
two
EOF
$ ls src
one three two
$ ls dst
$ rsync -av --files-from filelist.txt --remove-source-files src/ dst/
building file list ... done
one
two
sent 165 bytes received 70 bytes 470.00 bytes/sec
total size is 0 speedup is 0.00
$ ls src
three
$ ls dst
one two
答案2
如果您提供了 GNU 核心实用程序(或具有这些特定功能的其他实现),您可以使用它来基于文件列表xargs
构建参数列表:mv
cd A
xargs -rd '\n' -- mv -t B -- < file-list.txt
如果没有 GNU 实用程序,您仍然可以使用 while-read 循环。在 Bash 中可能是:
while IFS= read -r file; do
mv "A/$file" "B/$file"
done < file-list.txt
答案3
您可以轻松解决这个问题维姆通过以下 10 个简单步骤:
- 在 ViM 中打开一长串文件名。
- 键入
qa
以开始录制名为“a”的宏。 - 键入
y$
以提取(复制)文件名。 - 键入
imv A/
在文件名前面写入“mv A/”,然后按Escape
。 - 键入
A B/
并在行尾写入“B/”,然后按Escape
。 - 键入
pj^
以粘贴文件名并移动到下一行的开头。 - 按
q
停止录制宏。 - 键入
VG:normal @a
以重播“a”宏,直到文件末尾。 - 键入
:wq rename.sh
以另存为名为“rename.sh”的 bash 脚本并退出。 - 最后,在 bash 提示符下,键入
chmod +x rename.sh; ./rename.sh
将脚本标记为可执行并运行它。
答案4
这是一个不使用循环的 POSIX 兼容变体。中的项目file-list.txt
由换行符分隔。
cd A ; xargs -I{} -- mv -- {} B < file-list.txt
显然,这个变体不允许文件名包含换行符。此外,它还mv
单独为每个文件调用该命令。
这大卫·福斯特的变体使用xargs
和的 GNU 扩展mv
。它将 mv
为多个参数调用单个实例,并且对于长文件列表将更有效。它仍然不允许文件名包含换行符。要克服此限制,您可以使用该选项并用(NULL)字符-0
分隔文件名。\0
cd A ; xargs -r0 -- mv -t B -- < file-list.txt