查找名称与许多模式之一匹配的文件并复制到不同的目录

时间:2018-02-07 05:19:08

标签: linux unix sed find cp

我在Linux目录中有一组文件。我想将名称与许多模式之一匹配的文件复制到另一个目录;我将所有这些模式放在一个文本文件中。

有什么方法可以找到带有模式的所有文件并复制到目标文件夹?

到现在为止,我能够保持这样的模式:

find . -type f \( -name "*Patt1* -o -name "*Patt2*" - o -name "*Patt3*" \
    -o -name "*Patt4*" -o -name "*Patt5* -o -name "*Patt6*" \) \
    | xargs cp {} /home/DestinationFolder/.

我的模式文件如下所示:

PYTH
SPYD
ISIN
CUSIP
HELD
SEDO

2 个答案:

答案 0 :(得分:0)

您可以使用grep过滤文件名,使用-f选项从文件中读取模式:

find . -type f -printf '%f\0' | grep -zFf pattern.txt \
    | xargs -0 -I {} cp {} /home/DestinationFolder

由于您的模式根据您的注释只是固定字符串,因此我们可以将-F添加到grep选项,以将输入文件中的行解释为固定字符串。

为了适应文件名中任何可能的字符,我使用-printf '%f\0'打印文件名空字节分隔; grep -z从空字节分隔流中读取和写入;并且xargs -0期望空字节分隔输入。

答案 1 :(得分:0)

我在MacOS上。我的问题与你的问题非常相似,但我想使用正则表达式来匹配要操作的文件。第一个答案指出了我正确的方向,但遗憾的是(或不是?)我在MacOS上。显然,BSD find不喜欢-printf,而BSD grep不喜欢-z。所以,小提琴。

在MacOS(10.13:High Sierra)上,使用bash(我测试了MacOS提供的一个和GNU bash 4.4.19),以下内容可以满足您的需求。作为奖励,它对于包含空格(但不是所有奇怪的文件名)的文件名具有弹性,并允许模式扩展正则表达式而不仅仅是简单的固定字符串。下面的示例包括一个扩展的正则表达式模式(文件中的第一行),我实际上用它来执行类似的操作:将以_9.mpg等模式结尾的文件移动到另一个目录:

警告:为了让空间对于包含空格的文件(以及文件名中没有空格的文件来说很好看,呃??),我正在使用这个hack,这将导致bash在命令之间拆分管道新行,而不是空格:

 OLD_IFS=$IFS
 IFS=$(echo -en "\n\b")

这是一个测试“源”目录:

% ls -1 source
bad dog_1.mp3
bod dog.mp3
i am SEDO yeah

这是空的“目标”目录:

% ls ../target|wc -l
       0

您可以创建一个包含合法扩展正则表达式的模式文件,其中包含不包含特殊正则表达式字符的简单字符串。如果你谴责正则表达式而只想要简单的字符串(因此比我更理智),将上面的'grep -Ef'改为'grep -f':

% cat patterns.txt
_\d+\.m..$
PYTH
SPYD
ISIN
CUSIP
HELD
SEDO

这是带有肉的文件:

% cat generate-commands.sh
for f in $(find ${src} -type f | grep -Ef ${pats}); do
  echo mv \"$f\" \"${trg}/$f\"
done

我们走了!首先,cd进入源目录,然后使用所需的参数运行generate-commands文件:

% cd source
% src=. trg=../target pats=../patterns.txt . ../generate-commands.sh
mv "./i am SEDO yeah" "../target/./i am SEDO yeah"
mv "./bad dog_1.m4v" "../target/./bad dog_1.m4v"

然后,小心谨慎地考虑实际执行generate-commands.sh脚本输出的命令。

最后,除非你喜欢惊喜,否则杀死当前的shell或者执行此操作可能是个好主意:

IFS=$OLD_IFS