我正在编写一个Bash脚本,用文件夹B(目标)替换文件夹A(源)中的文件。但在此之前,我想记录2个文件。
如何在Bash中完成此操作?我尝试过使用diff -qr
,但会产生以下输出:
Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ
我也试过这个
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
但它并没有给我我需要的结果范围。这里的斗争是数据不是正确的格式,我只想要文件而不是目录显示在文本文件中,例如:
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
答案 0 :(得分:2)
目录B(new/
)中比目录A(old/
)更新的文件列表:
find new -newermm old
这仅运行find
,并检查由new/
过滤的-newerXY reference
的内容,X
和Y
都设置为m
(修改时间)和reference
是old
目录本身。
目录B(new/
)中缺少但目录A(old/
)中存在的文件:
A=old B=new
diff -u <(find "$B" |sed "s:$B::") <(find "$A" |sed "s:$A::") \
|sed "/^+\//!d; s::$A/:"
这会将变量$A
和$B
设置到目标目录,然后对其内容运行统一的diff
(使用process substitution定位find
并使用sed
删除目录名称,以免diff
混淆。最后的sed
命令首先匹配添加(以+/
开头的行),修改它们以用目录名和斜杠替换+/
,并打印它们(其他行是去除)。
这是一个将创建文件的bash脚本:
#!/bin/bash
# Usage: bash script.bash OLD_DIR NEW_DIR [OUTPUT_FILE]
# compare given directories
if [ -n "$3" ]; then # the optional 3rd argument is the output file
OUTPUT="$3"
else # if it isn't provided, escape path slashes to underscores
OUTPUT="${2////_}-newer-than-${1////_}"
fi
{
find "$2" -newermm "$1"
diff -u <(find "$2" |sed "s:$2::") <(find "$1" |sed "s:$1::") \
|sed "/^+\//!d; s::$1/:"
} |sort > "$OUTPUT"
首先,这确定输出文件,该文件来自第三个参数,或者使用替换创建其他输入,以便在存在路径时将斜杠转换为下划线,例如,以{{1}运行将其文件列表输出到当前工作目录中的bash script.bash /usr/local/bin /usr/bin
。
这将两个命令组合在一起,然后确保它们已排序。不会有任何重复,所以你不必担心(如果有的话,你会使用_usr_local_bin-newer-than-_usr_bin
)。
您可以在调用此脚本时通过更改参数的顺序来获取第一个和第二个文件。