如何比较最新的两个文件是否与shell相同?

时间:2015-11-19 18:00:55

标签: shell

我想检查最新的两个文件是否不同。 这是我的代码,它不起作用。

#!/bin/bash
set -x -e

function test() {
  ls ~/Downloads/* -t | head -n 2 | xargs cmp -s
  echo $?
}

test

感谢。

1 个答案:

答案 0 :(得分:1)

假设您有GNU查找和GNU排序:

#!/bin/bash
#      ^^^^ - not /bin/sh, which lacks <()

{
  IFS= read -r -d '' file1
  IFS= read -r -d '' file2
} < <(find ~/Downloads -type f -mindepth 1 -maxdepth 1 -printf '%T@ %p\0' | sort -r -n -z)

if cmp -s -- "$file1" "$file2"; then
  echo "Files are identical"
else
  echo "Files differ"
fi

如果您的操作系统是MacOS X,并且您通过MacPortshomebrewfink安装了GNU findutilscoreutils,则可能需要更换find gfindsort gsort获取GNU而不是这些工具的BSD实现。

要点:

    要求
  • find[epoch-timestamp] [filename][NULL]的形式发出一个流。这样做是因为NUL是路径名中不能存在的唯一字符。
  • sort被要求以数字方式对此流进行排序。
  • 流的前两项被读入shell变量。
  • 在选项之后和位置参数之前使用--参数cmp确保文件名永远不会被解析为位置参数,即使是以-开头。

那么,为什么不使用ls -t?考虑(作为示例)如果您使用命令touch $'hello\nworld'创建了一个文件,并且在其名称的中途有一个文字换行符,会发生什么;根据您的ls版本,它可能会以hello?worldhello^Mworldhello\nworld的形式发布(在任何一种情况下,文件名都不会实际存在)如果被视为文字而不是全局展开),或者作为两行,helloworld。这会弄乱你的管道的其余部分(而像带有空格的文件名一样简单的事情也会使用默认选项中断xargs,文字引号也会中断; xargs只有在与文字引号一起使用时才真正安全参数-0将内容视为NUL分隔,但在与GNU扩展名-d $'\n'一起使用时,它与默认值相比不太安全。

另见: