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