![根据文件中的部分名称复制文件](https://linux22.com/image/152783/%E6%A0%B9%E6%8D%AE%E6%96%87%E4%BB%B6%E4%B8%AD%E7%9A%84%E9%83%A8%E5%88%86%E5%90%8D%E7%A7%B0%E5%A4%8D%E5%88%B6%E6%96%87%E4%BB%B6.png)
我的一个文件夹中有数百万个 xml 文件。文件的名称遵循特定的模式:
ABC_20190101011030931_6049414.xml
对此,我只对 xml 之前的最后一组数字感兴趣6049414
。我在一个文本文件中列出了大约 8000 个这样的数字。文本文件中的详细信息如下 - 一行中的数字:
104638
222885
108880071
我使用以下代码从与文本文件中给出的编号匹配的文件夹中移动文件:
#folder where the xml files are stored
cd /home/iris/filesToExtract
SECONDS=0
#This line reads each number in the hdpvr.txt file and if a match is found moves that file to another folder called xmlfiles.
nn=($(cat /home/iris/hdpvr.txt));for x in "${nn[@]}";do ls *.xml| grep "$x"| xargs -I '{}' cp {} /home/iris/xmlfiles;done
#this line deletes all the other xml files from filesToExtract folder
find . -name "*.xml" -delete
echo $SECONDS
我面临两个问题。 1 尽管存在匹配,但某些文件并未移动;2. 即使在文件名的中间部分找到匹配
from this ABC_20190101011030931_6049414.xml -> this 20190101011030931
如果找到匹配项,它仍然会移动......我怎样才能获得精确的匹配项并移动文件。
答案1
另一个解决方案,感谢格伦·杰克曼!
#!/bin/bash
# folder where the xml files are stored
xmldir=/home/iris/filesToExtract
# xml backup folder
backupdir=/home/iris/xmlfiles
while read -r line; do
mv -t "$backupdir" *_*_${line}.xml 2>/dev/null
done <"$xmldir/hdpvr.txt"
rm -i *.xml
模式*_*_${line}.xml
用于查找目录中的文件。
如果要立即删除剩余的 xml 文件,请替换rm -i *.xml
为。rm *.xml
答案2
这样的事情能完成这份工作吗?
pushd /home/iris/filesToExtract
for i in $(</home/iris/hdpvr.txt); do find . -mindepth 1 -maxdepth 1 -type f -name "*_$i.xml" -print0 | xargs -r -0 -i mv "{}" /home/iris/xmlfiles; done
find . -mindepth 1 -maxdepth 1 -type f -name "*.xml" -delete
popd
- Pushd 会将您移至指定目录
- for+find 行将从文本文件中获取 ID,查找以 _ID.xml 结尾的文件并将它们移动到 /home/iris/xmlfiles 文件夹中
- 最后一个查找将删除未移动的文件,但仅在此文件夹中,而不是子文件夹中
- popd 会将您放回原始目录
您也可以使用 mv 进行残酷的操作,但如果找不到文件,它会抛出错误
pushd /home/iris/filesToExtract
for i in $(</home/iris/hdpvr.txt); do mv "*_$i.xml" /home/iris/xmlfiles; done
find . -mindepth 1 -maxdepth 1 -type f -name "*.xml" -delete
popd