比较bash中两个变量的内容

Mar*_*tin 35 bash diff

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

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

那些变量将包含文本.如何比较这两个?一种选择是使用像这样的diff(1)实用程序:

diff -u <(echo "$data") <(echo "$file")
Run Code Online (Sandbox Code Playgroud)

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

and*_*otn 81

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

通过在bash联机帮助页中搜索字符<(,您会发现这称为"进程替换".

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

$ echo <(echo foo)
/dev/fd/63
Run Code Online (Sandbox Code Playgroud)

这表明临时文件实际上只是管道"文件描述符63".虽然它出现在虚拟/dev文件系统上,但永远不会触及磁盘.

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

echo <(echo foo) <(echo foo) ... 997 repetitions ... <(echo foo)
Run Code Online (Sandbox Code Playgroud)

在我的旧Mac笔记本电脑上耗时0.225秒,在同一台笔记本电脑上运行的Ubuntu虚拟机耗时2.3秒.按照1000次调用进行划分,这表明进程替换的时间不到3毫秒 - 运行时间完全相形见绌diff,而且可能不需要担心任何事情!

  • 注意甚至`echo foo> foo; 猫foo; rm foo`也不太可能触及磁盘.如果在将vfs刷新到物理分区之前删除了临时文件,则无法进入盘片. (2认同)

det*_*acy 6

这最适合我:

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

diff <( echo "$var1" ) <( echo "$var2" )
Run Code Online (Sandbox Code Playgroud)

首先我设置了 var1 和 var2。然后我与 <( ) 元素进行 diff 来表示输入是一个变量。


Wil*_*ell 5

test "$data" = "$file" && echo the variables are the same
Run Code Online (Sandbox Code Playgroud)

如果你想要冗长,你也可以这样做:

if test "$data" = "$file"; then
  : variables are the same
else
  : variables are different
fi
Run Code Online (Sandbox Code Playgroud)