![比较文件并选择较大的文件](https://linux22.com/image/146729/%E6%AF%94%E8%BE%83%E6%96%87%E4%BB%B6%E5%B9%B6%E9%80%89%E6%8B%A9%E8%BE%83%E5%A4%A7%E7%9A%84%E6%96%87%E4%BB%B6.png)
有两个目录,有很多文件。这些文件的名称始终匹配,但大小并不总是匹配。例如:
/dir1
|-file1 (1 MB)
|-file2 (2 MB)
|-file3 (3 MB)
/dir2
|-file1 (1 KB)
|-file2 (2 MB)
|-file3 (10 MB)
如您所见,文件名匹配,但文件大小仅在 file2 中匹配。如何比较这两个目录中的文件并仅选择较大的文件?示例中的输出必须是“/dir2/file3”。
如果 dir1 中的文件比 dir2 中同名的文件大,则不执行任何操作。我只对 dir2 中比 dir1 中的文件大的文件感兴趣
我写了一个脚本,但只有在 dir2 中找到一个更大的文件时它才有效。
#!/bin/bash
diff -q $1 $2 | awk '{ print $2,$4 }' > tempfile.txt
A=`cat tempfile.txt | cut -d ' ' -f 1`
B=`ls -s $A | cut -d ' ' -f 1`
C=`cat tempfile.txt | cut -d ' ' -f 2`
D=`ls -s $C | cut -d ' ' -f 1`
if [ "$D" -gt "$B" ]; then
echo $C
fi
答案1
#!/usr/bin/env zsh
zmodload -F zsh/stat b:zstat
for file2 in dir2/*(.); do
file1="dir1/${file2##*/}"
if [ -f "$file1" ] &&
[ "$( zstat +size "$file2" )" -gt "$( zstat +size "$file1" )" ]
then
printf '%s is bigger than %s\n' "$file2" "$file1"
fi
done
这是一个zsh
shell 脚本,它使用内置命令zstat
来便携式获取文件大小。
该脚本将循环遍历目录中具有非隐藏名称的所有常规文件dir2
。对于其中的每个文件,dir2
将为 中的文件构造相应的路径名dir1
。如果文件dir1
存在并且是常规文件(或常规文件的符号链接),则比较两个文件的大小。如果输入的文件dir2
明显更大,则会输出一条短消息。
该模式dir2/*(.)
将仅匹配目录中常规文件的非隐藏名称dir2
。这(.)
是一个zsh
特定的修饰符,*
使其仅匹配常规文件。
该表达式"dir1/${file2##*/}"
将扩展为以 开头并包含之前所有内容(包括最后删除的内容dir1/
)的值的路径名。这可以更改为.$file2
/
"dir1/$( basename "$file2" )"
答案2
#!/bin/bash
get_attr() {
# pass '%f' to $2 to get file name(s) or '%s' to get file size(s)
find "$1" -maxdepth 1 -type f -printf "$2\n"
}
while read -r file
do
(( $(get_attr "dir2/$file" '%s') > $(get_attr "dir1/$file" '%s') )) \
&& realpath -e "dir2/$file"
done < <(get_attr dir2 '%f')
这假设 中的所有文件dir2
与 中的文件具有相同的名称dir1
,如上所述。
realpath
打印文件的绝对路径。
该脚本还比较隐藏文件(以 开头的文件.
)。