我想找出文件中字节的差异。但是,du/diff 命令加上 -a 也会列出目录和子目录。我只想要子目录和目录中的文件,而不是这些。
我知道--exclude选项,但我不知道如何操作它来做到这一点。谢谢。
我的操作系统是 Linux Debian。
我的命令是
dira=/mnt/hdd_a/;
dirb=/mnt/hdd_b/;
diff -u <(cd $dira && du -ab | sort -k2) <(cd $dirb && du -ab | sort -k2)
我也不太理解输出。我认为目录有 + 或 - 的差异是出于多种原因,例如属性。我不关心这个。但是,在数百个文件中,diff 打印出一些没有 + 或 - 的文件。为什么?它们可能在大小以外的其他属性上有所不同?
--- /dev/fd/63 2023-08-22 01:38:15.775099368 +0300
+++ /dev/fd/62 2023-08-22 01:38:15.775099368 +0300
@@ -1,6 +1,6 @@
-364123856483 .
+364123860579 .
435823780 ./vid_01.mkv
-33781164566 ./news_a
+33781168662 ./news_b
19110023 ./news_c/covers_09.rar
161634304 ./news_d/video_d7.avi
17080320 ./news_e/video_d17.avi
据我了解,“u”选项仅打印 3 行。我想要所有不同的行,而且只打印这 3 行。不打印相同的行(文件大小)。
使用 diff --changed-group-format='%<' --unchanged-group-format='' <(cd "$dira" && du -ab | sort -k2) <(cd "$dirb" && du -ab | sort -k2)
打印一些文件及其大小,没有任何“+/-”指示。所以我不知道差异是来自源文件还是来自目标文件。请注意,目标中缺少整个文件。
答案1
du/diff 命令带有 -a 列表,还列出目录和子目录。我只想要子目录和目录中的文件,而不是这些文件。
我知道--exclude选项,但我不知道如何操作它来做到这一点。谢谢。
如果我理解正确的话,你只想看到所有文件在目录树中,不是任何内容的总大小目录本身。不幸的是,--exclude
选项du
似乎不支持使用类似的东西/
来指示目录,例如du --exclude='*/'
仍然会输出目录的大小。
您无需使用命令du
本身的任何选项来过滤目录,而是可以使用类似命令find
来仅获取文件列表(例如使用其-type f
选项),然后将此列表传递给du
。该命令在其自己的行上输出每个文件名,我们可以借助find
将此文件名列表传递给。该命令要求各个参数由任何空格字符(例如空格、制表符、换行符)分隔,但如果任何文件名包含空格,则不会按我们的预期执行,因此我们改为使用 来指示用 NULL 字符分隔文件名,并使用来指示期望这样的输入:du
xargs
xargs
xargs
find
-print0
xargs
-0
find . -type f -print0 | xargs -0 du -b
我想找出文件中字节的差异。 [...] diff 打印一些没有 + 或 - 的文件。为什么?它们可能除了大小之外在其他属性上有所不同?
为此,您需要直接比较要比较的两个文件的文件大小。该diff
命令不执行此操作。相反,diff
它用于比较内容两个文件,例如如果文件a.txt
包含以下内容......
a
b
c
...文件b.txt
包含以下内容...
a
b
d
然后diff a.txt b.txt
输出:
3c3
< c
---
> d
这告诉您两个文件之间的差异在于:在第 3 行,删除了a.txt
该行( ) 并且添加了该行( )。c
<
d
>
使用diff
此-u
选项会导致其将输出格式化为“统一上下文”补丁文件,如patch
命令所用,其风格与其他工具(如 Git)使用的补丁文件类似。也就是说,diff -u a.txt b.txt
它会返回以下内容:
--- a.txt 2023-08-22 00:38:07.477617454 +0100
+++ b.txt 2023-08-22 00:38:12.533616240 +0100
@@ -1,3 +1,3 @@
a
b
-c
+d
这应该有助于您理解为什么在所运行命令的输出中看到+
和。具体来说,输出 的内容大小,按项目名称排序,因此需要两个这样的输出并向您显示这些输出之间的差异。 以 开头的行表示 中存在但不在 中的文件,以 开头的行则相反。-
cd $dira && du -ab | sort -k2
$dira
diff -u <(...) <(...)
-
$dira
$dirb
+
该命令不会执行任何更智能的操作,例如直接向您显示和diff
中特定文件对之间的文件大小差异。为此,您需要以某种方式指定要比较哪些文件对的大小。$dira
$dirb
例如,如果你想比较$dira/news_a
和的大小,那么你应该直接比较。如果你只想比较和中文件名为 的$dirb/news_b
文件对的大小$dir_a
$dir_b
一模一样,例如$dir_a/news_a
和$dir_b/news_a
,那么这可以通过编程来完成,如下面的 Bash 脚本所示:
#!/bin/bash
script_location="$( dirname "$(readlink -f "${BASH_SOURCE:-$0}")" )"
dir_a="$1"
dir_b="$2"
cd "$dir_a"
dir_a_filenames="$(find . -type f)"
cd "$script_location"
cd "$dir_b"
dir_b_filenames="$(find . -type f)"
# Combine filename lists
all_filenames="$( sort -u <(echo "$dir_a_filenames") <(echo "$dir_b_filenames") )"
# For each filename in $all_filenames, compare the size of that file in $dir_a with the same file in $dir_b
IFS=$'\n'
cd "$script_location"
for file in $(echo "$all_filenames"); do
file_a="$dir_a/$file"
file_b="$dir_b/$file"
file_a_size="$(if [ -f "$file_a" ]; then stat --format='%s' "$file_a"; else echo 0; fi)"
file_b_size="$(if [ -f "$file_b" ]; then stat --format='%s' "$file_b"; else echo 0; fi)"
size_diff=$(($file_b_size - $file_a_size))
echo -e "$file\tA size = $file_a_size\tB size = $file_b_size\tSize difference = $size_diff"
done
环境$IFS
变量定义在循环等结构中使用哪些字符作为项目分隔符for
。在这里,我们将其设置为换行符,$'\n'
原因与我们之前使用 NULL 分隔符的原因类似xargs
。
我们使用stat
而不是du
来获取文件大小,因为这样更快一些,并且我们将不存在的文件的大小视为零,以便报告其大小并计算大小差异;该命令[ -f filename ]
用于检查文件是否filename
存在。
Bash 语法$((...))
用于执行计算,例如$((2+3))
输出5
;这里我们只是从另一个文件大小中减去一个文件大小。