54

我在 bash 脚本中有一个变量$data和变量:$file

data=$(echo "$(printf '%s\n' "${array[@]/%/$'\n\n'}")")
file=$(<scriptfile_results)

这些变量将包含文本。如何比较这两者?一种选择是使用diff (1) 实用程序,如下所示:

diff -u <(echo "$data") <(echo "$file")

这是比较两个变量的内容的正确而优雅的方法吗?另外<( )技术怎么称呼?据我了解,为每个<( )临时文件(命名管道)创建..

4

5 回答 5

102

是的,diff <(echo "$foo") <(echo "$bar")很好。

通过在bash 手册页中搜索字符<(,您可以发现这称为“进程替换”。</p>

您不必担心创建临时文件的效率,因为临时文件实际上只是一个管道,而不是磁盘上的文件。试试这个:

$ echo <(echo foo)
/dev/fd/63

这表明临时文件实际上只是管道“文件描述符 63”。尽管它出现在虚拟/dev文件系统上,但从未接触过磁盘。

您可能需要担心的实际效率问题是“流程替换”中的“流程”部分。Bash fork 另一个进程来执行echo foo. 在某些平台上,如 Cygwin,如果频繁执行,这可能会非常慢。但是,在大多数现代平台上,forking 非常快。我刚刚尝试通过运行脚本一次执行 1000 个进程替换:

echo <(echo foo) <(echo foo) ... 997 repetitions ... <(echo foo)

在我的旧 Mac 笔记本电脑上花费了 0.225 秒,在同一台笔记本电脑上运行的 Ubuntu 虚拟机中花费了 2.3 秒。除以 1000 次调用,这表明进程替换所需的时间不到 3 毫秒——这与 的运行时间相比完全相形见绌diff,而且您可能不需要担心任何事情!

于 2012-11-18T04:18:20.007 回答
7
test "$data" = "$file" && echo the variables are the same

如果你想详细一点,你也可以这样做:

if test "$data" = "$file"; then
  : variables are the same
else
  : variables are different
fi
于 2012-11-18T03:33:04.577 回答
5

这对我最有效:

var1="cat dog mule pig"
var2="cat dog ant"

diff <( echo "$var1" ) <( echo "$var2" )

首先我设置了 var1 和 var2。然后我用 <( ) 元素区分输入是一个变量。

于 2014-10-10T16:21:13.470 回答
3
~ cat test.sh   

#!/usr/bin/env bash

array1=(cat dog mule pig)
array2=(cat dog ant)

diff -ia --suppress-common-lines <( printf "%s\n" "${array1[@]}" ) <( printf "%s\n" "${array2[@]}" )
于 2014-10-13T12:09:30.653 回答
2

使用comm

comm -23 <(echo $variableA | tr ' ' '\n' | sort) <(echo $variableB | tr ' ' '\n' | sort)
于 2019-09-12T12:39:56.390 回答