我在当前目录中有一堆 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 ) 中的任何有效数字。