如何在 Bash 脚本中查找并将文件复制到文件夹

如何在 Bash 脚本中查找并将文件复制到文件夹

在文件夹中我有文本文件。我想找到它们并复制到创建的文件夹中。一切正常。代码创建一个文件夹并复制文件,但控制台显示:

cp: './02_2017/lks07.txt' and '02_2017/lks07.txt' are the same file

02_2017 创建文件夹。

代码有问题,但我不知道是什么

这是代码:

date1=$(date '+%Y-%m-%d' -d "-0 month -$(($(date +%d)-1)) days")
date2=$(date '+%Y-%m-%d' -d "-$(date +%d) days +1 month")
date=$(date +'%m_%Y')
mkdir -m 777 $date
find ./ -type f -name '*.txt' -newermt $date1 ! -newermt $date2 -exec cp {} $date \;

有人可以帮我解决这个问题吗?

答案1

出现此问题的原因是find将按顺序查找文件。例如,考虑以下目录布局:

$ tree
.
├── 02_2017
│   └── foo.txt
└── bar.txt

当您运行find命令时,它会首先在顶级目录中查找任何匹配的文件,因此它会找到bar.txt并将其移动到02_2017。然后,它会进入02_2017并在那里查找文件。现在有一个02_2017/bar.txt文件,因此它会尝试将其复制到自身,失败并打印该错误消息。

这其实不是问题。您的脚本运行良好,并且正确执行了任务。您可以放心地忽略该错误。

如果它确实困扰您,您可以通过添加命令-maxdepth 1来修复它find,这样它就不会进入子目录:

find ./ -type f -name '*.txt' -newermt $date1 ! -newermt $date2 -exec cp {} $date \;

或者,更好的方法是从 find 的搜索路径中排除目标目录:

find ./ -type f -not -path './02_2017/*' -name '*.txt' -newermt $date1 ! -newermt $date2 -exec cp {} $date \;

答案2

我尝试完成相同的任务,但不久前我收到了相同的错误。我的想法是找到一段时间内最近修改的所有文件并分别备份它们。尽管值得一提的是,尽管 cp 出现错误,但文件仍在被复制。我仍然不喜欢脚本中出现错误,所以我做了如下调整:

find /mnt/net_shares/common/ -type f -mtime -15 >> /tmp/common_mod15.$$.txt

这将查找过去 15 天内修改的所有文件并在文本文件中创建它们的列表。$$ 运算符是正在运行的脚本的进程 ID。这确保如果我有重叠的进程,它们不会使用同一个文件,使其对进程 ID 是唯一的。

rsync -azv --files-from=/tmp/common_mod15.$$.txt / /mnt/hd2/backups/local/mod15/common/

第二步是使用 rsync 而不是 cp。您可以使用--files-fromswitch 定义一个文本列表,它还会比较文件并仅从我的备份位置的文件中复制已修改的内容。而cpcp 则会复制并替换所有内容。

请注意,'额外'斜线/tmp/common_mod15.$$.txt **/** /mnt...不是拼写错误,但我不记得我为什么需要它。与相对路径和绝对路径有关。根据您生成的列表,您可能需要它,也可能不需要。但我发现您也在使用相对路径(./ 运算符),所以您可能确实需要它。

不用说,要在终端中测试它,您需要删除$$操作员。它只属于创建进程 ID 的脚本。还请记住删除临时创建的文件以保持/tmp文件夹干净。

相关内容