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

Find files with names matching one of many patterns and copy to different directory

我在 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

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

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

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

为了容纳文件名中的任何可能的字符,我使用 -print0 打印文件名空字节分隔; grep -z 读取和写入空字节分隔流; xargs -0 需要空字节分隔输入。

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

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

警告:为了使空格适合其中包含空格的文件(谁的文件名中没有空格,嗯??),我正在使用此 hack,这将导致 bash在换行符而不是空格上拆分命令之间的管道:

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

这里是测试"source"目录:

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

这是空的 "target" 目录:

% 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