如何移动不使用的文件?

如何移动不使用的文件?

我想移动目录中当前未使用的文件。我觉得lsoffind和的某种组合xargs可以起作用,但我做不到。到目前为止,我创建了以下命令:

lsof mydir/*|awk '(NR>1){print $9}

这给了我一个正在使用的文件列表。如果我能得到一个没有被使用的文件列表,那么像 xargs 这样的命令就可以mv对这些文件发出一个。我似乎找不到一个优雅的方式来做到这一点。有人能给我一些提示吗?

答案1

我会这么做。

find $dir -maxdepth 1 | sort > $other_dir/all_files
lsof $dir/* | awk '(NR>1) {print $9}' | sort > $other_dir/in_use_files
comm -2 -3 $other_dir/all_files $other_dir/in_use_files

来自 comm(1):

NAME
       comm - compare two sorted files line by line

SYNOPSIS
       comm [OPTION]... FILE1 FILE2

    ...

       -2     suppress lines unique to FILE2

       -3     suppress lines that appear in both files

现在只需将其重新格式化为一系列mv语句即可。可能像这样:

while IFS= read file ; do
    mv "$file" "$destination/"
done < <(comm -2 -3 all_files in_use_files)

或者如果您愿意,可以使用另一个中间文件。

答案2

也许这不是最好的方法,但只需几分钟就可以编写代码:

获取打开的文件列表(如果尚未排序则进行排序)

获取所有文件的列表(如果尚未排序则进行排序)

比较两个列表

xargs 无论如何

这里的步骤数将使本来应该引起关注的事情变得明显,即竞争条件——您选择它们​​时正在使用的文件可能不是您实际移动它们时正在使用的文件。

答案3

感谢@Sorpigal 的建议,我找到了一种无需循环即可完成此工作的简单方法:

comm -2 -3 <(find $dir -maxdepth 1 -type f|sort) <(sudo lsof $dir/* | awk '(NR>1) {print $9}'|sort) | xargs -I {} mv {} $move_dir

我不确定竞争条件,但对我而言这并不重要。文件打开一次进行写入,然后应关闭,直到移动为止。

答案4

这就是定影器的用途。

/var/log/apache2
$ fuser access.log
/var/log/apache2/access.log: 2132 15456 16414 19555 19622
/var/log/apache2
$ fuser access.log 2>/dev/null
 2132 15456 16414 19555 19622
/var/log/apache2
$ if [ ! -z "$(fuser access.log 2>/dev/null)" ]
> then
>   echo "this file is in use"
> else
>   echo "this file is not in use"
> fi
this file is in use

相关内容