文件文本列表中的Linux(MV或cp)特定文件?


34

我有许多文件的目录,例如服务器上的50,000 pdf和其他文件。我需要将特定的移动到另一个目录。我可以生成需要以csv或任何其他文本格式移动的文件的列表。

我需要做的是运行bash脚本并将文本文件中列出的文件移动或复制到另一个目录。

有一个简单的方法吗?任何建议或资源将不胜感激。


此外,将文件添加到目录后,它们会被随机命名。没有命名约定或任何可用于移动特定文件的逻辑。
Jestep 2010年

Answers:


26

rsync的具有可采取文件的列表,以过程(几个选项--files-from--include-from等等)。

例如,这将达到目的:

rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory

2
例如:rsync -a /source/directory --files-from=/full/path/to/listfile /destination/directory
anneb

28

为了避免无用的使用cat(如果您不使用rsync):

xargs -a file_list.txt mv -t /path/to/dest

如果文件每行列出一个,则它将处理任何有效的文件名,除非它包含换行符。


2
这种方法的一个缺点是,如果列表中的文件包含路径名(即它们不在同一目录中),则使用mv会将所有文件折叠到同一目标目录中。rsync接受的答案中的方法不受此限制。
杰森R

另外,我尝试了此命令,xargs会在包含单引号(“不匹配的单引号”)的任何文件上中断
James Beninger 2012年

这对我有用,因为我实际上想要来自同一目标目录中不同源路径的文件。
PseudoNoise

15
for file in `cat listoffiles`; do mv "$file" /path/of/destination ; done

假设bash,listoffiles每行包含一个文件。我对rsync路由的唯一反对意见是,OP要求一种移动文件而不复制文件的方法。rsync比皇室婚礼拥有更多的标志,所以我敢肯定它可以被进一步修改以做到这一点,但是有时候更简单更好。


1
这个解决方案使我印象最深刻。我最终用rsync而不是cp或mv来使用它,只是因为我需要相对文件路径选项。
三明治

4
很好,只是我在空格方面遇到了问题,所以我将其修改为:while read -r file; do mv "$file" /path/of/destination ; done < listoffiles
user1182474 '16

1
@ user1182474谢谢,很好地使用了输入重定向。顺便说一句,对答案表示满意的传统方法是投票!
MadHatter支持Monica

1
@ user1182474谢谢你!许多修改的最后一步必须有点盲目地将OSX备份实用程序移植到Android!
Charlie Gorichanaz

4

这取决于您拥有的文本文件的格式。例如,如果您编写了文件列表,以使每个文件都位于新行中。您可以像这样使用xargs:

$ cat your_text_file | xargs cp -t /path/to/destination

另外,您可以将findcommand与-execoption 一起使用。复制/移动文件。


3
rsync --files-from=file_list.txt /path/to/source/ /path/to/dest/

Rsync相对于cpor mv命令具有更多的好处,因为如果不存在,它将自动创建文件夹。


/path/to/source从文件列表获取路径时为什么需要?
bzero

@bzero也许文件列表可以包含相对路径?
DreadfulWeather

2

我认为rsync答案是一个更好的答案,但这只是另一种选择:

tar -cf - -T FILE_OF_FILENAMES_TO_MOVE.txt |(cd /path/to/new/dir && tar -xvf -)

这对于Dockerfile很有好处,因为ubuntu基本映像中提供了tar,但rsync中没有。
kristianp

1

我不小心将目录的完整内容复制到了目标目录中,而不是移动了完整目录。这导致目标目录混乱,而不是将原始目录添加到目录中。

为了解决这个问题,我做了以下工作:

ls -rt /path/to/cluttered/destination/directory/ > /opt/dircheck/filestomove 上面的命令创建filestomove文件,该文件将是目标目录所有内容的列表,按时间反向排序,即从最早到最新。

然后,我创建了现在杂乱无章的目标目录的子目录,以将内容移动到其中。

mkdir /path/to/cluttered/destination/directory/newsubdirectory

然后,我重复了目录列表,但要列出屏幕并显示更多详细信息。

ls -lrht /path/to/cluttered/destination/directory/ 该行列出了按日期升序排序的目录(按时间反向排序),并显示了更多信息,包括当前混乱的目标目录中每个文件的日期/时间戳。我指的是此内容,从顶部开始显示我想保留的目录和文件。在文件的日期/时间戳记中,所有新文件都将以不存在的地方出现间隙。

然后,我编辑了在上面第一步中创建的filestomove文件(按日期排序),并从列表中删除了一些我想保留在原始目录中的文件。

vim /opt/dircheck/filestomove 从顶部删除所有您不想移动的文件。

然后,使用本文前面列出的命令将列表中的文件移动到我创建的新目录中。

sudo xargs -a /opt/dircheck/filestomove mv -t /path/to/cluttered/destination/directory/newsubdirectory

这很快就移动了所有文件。(注意:开始时可能不需要sudo,这是文件权限问题)。

现在,我原来的目标目录干净整洁,并包含一个新目录,其中包含所有混乱的文件和目录。


1

如果(且仅当)文件名中没有任何讨厌的字符(空格,换行符,这会使xargs混淆如何将其分解为单个参数),并且生成了一个由换行符分隔的文件列表(一个文件每行),您可以执行类似操作。

cat filenames.txt | xargs mv -t /path/to/move/files/to

(总的来说,请参见man xargs,这太棒了)

如果您的特定MV没有-t选项,则还可以进行一些欺骗性的操作,例如

( cat filenames.txt; echo; echo /path/to/move/files/to ) | xargs mv

注意-如果碰巧其中包含换行符的文件名,则这两个文件均无法正常工作。


然而; 看到Ignacio的答案,rsync就是为此而设计的。
Kjetil Joergensen

cpmv等等-tbsd上没有选项,并且第二个带有subshel​​l的示例对我不起作用(/path/to/move添加为最后一个文件名)

1
@ w17t –听起来filenames.txt没有以换行符结尾,或者将newline添加到filenames.txt的末尾,或者执行类似的操作(cat filenames.txt; echo; echo /path/to/move/files/to) | xargs mv
Kjetil Joergensen

0

尝试类似:

cat list.txt | while read line; do mv "$line" /images; done

本来可以while read line; do mv $line /images; done < list.txt 作为一个命令
点燃2015年

0

在我需要将所有PNG文件从特定路径(和所有子目录)复制到新位置并同时保留目录结构的情况下,以下代码为我工作:

rsync -av --prune-empty-dirs --include='*/' --include='*.png' --exclude='*' source/ destination/

由于RSYNC首先创建目录结构的镜像,然后同步文件,所以最终可能会留下多余的空文件夹。我使用--prune-empty-dirs标志删除了这些空目录。

我没有任何隶属关系,但认为应该对启发该解决方案的消息来源表示赞赏:http : //techblog.zabuchy.net/2011/transfer-only-selected-file-types-with-rsync/

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.