从命令输出中比较两个文件

从命令输出中比较两个文件

我在当前目录中有一堆 xml 文件。

问题1。

据我所读, eval 返回结果并将其存储在变量中。但我在使用以下命令时遇到错误

find ./ -name '*.xml' | file=$(eval awk '{print $0}') ; echo $file

编辑(在省略 cas 指出的 eval 之后)-

省略 eval 只是返回一个空字符串。

find ./ -name '*.xml' | file=$(awk '{print $0}') ; echo $file

问题2。

我只是想学习 bash,因此我做了一个复杂的序列,将前两个文件与 find 的输出进行比较。复杂的序列只是为了理解bash编程的概念。

find ./ -name '*.xml' | file=$(awk '{print $0}') ; echo $file && diff -y $(sed '2q;d' $file) $(sed '1q;d' $file)

答案1

下面是一个非常简短的示例,说明了在 bash 中使用数组来实现此目的的一种方法:

#!/bin/bash

IFS=$'\n' files=( $(find . -name '*.xml' | head -n 2) )

if [[ -n ${files[0]} && -n ${files[1]} ]] ; then
  diff "${files[0]}" "${files[1]}"
fi

这将运行find ... | head -n 2, 命令,将每一行(返回的文件名)存储到 array 中$files。如果前两个数组元素(0 和 1)非空,则它使用这些文件名运行 diff。

请注意,如果任何目录或文件名包含换行符,这将中断。

答案2

您可以使用:

diff "$(find . -type f -name 'diff')" "$(find . -type f -name 'diff2')"

通过这种方式您可以搜索差异文件,搜索差异2文件并将它们与差异工具。

答案3

为了扩大已接受的答案,为了整体理解,我发布了我自己的答案。

问题1的解决方案。

第一个问题是eval的使用。 eval 在这里是不必要的。使用 $(...) 进行命令替换就足够了

find ./ -name '*.xml' | files=$(awk '{print $0}') ; echo $files

第二个问题是管道。正如 @cas 所指出的 - 管道在它们自己的子 shell 中运行。因此变量文件是空的。为了解决这个问题,删除 awk 并将 find 的结果直接存储在变量中。

files=$(find ./ -name '*.xml') ; echo "${files}" 

但是,上面的命令不是数组。为了使其成为数组,请使用括号。

files=($(find ./ -name '*.xml')) ; echo "${files[0]}" 

需要被完成。现在,在变量 ${files} 中使用双引号是一个很好的做法,因为否则文件名中的空格会产生问题。除此之外,下一个好的实践是使用 IFS 。这可以确保 shell 不会在空格或制表符上进行分词。IFS=$'\n'在将内容存储在变量 $files 中之前,会在新行( find 的输出)上进行分词。

IFS=$'\n' files=($(find ./ -name '*.xml')) ; echo "${files[0]}" 

因此,比较两个文件或任意两个文件的最终命令是

files=($(find . -name '*.sh')) ; echo "${files[0]}" ; diff -y "${files[0]}" "${files[1]}"

这里的 0 和 1 可以替换为数组 ( $files ) 中的任何有效数字。

相关内容