Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux bash/awk脚本比较两个不同文件夹中所有文件的内容_Linux_Bash_Shell_Loops_Awk - Fatal编程技术网

Linux bash/awk脚本比较两个不同文件夹中所有文件的内容

Linux bash/awk脚本比较两个不同文件夹中所有文件的内容,linux,bash,shell,loops,awk,Linux,Bash,Shell,Loops,Awk,我在Linux服务器中有两个diff目录,其中来自两个diff服务器的.csv文件不断出现。两个目录中文件的文件名相同。 我想要一个bash/awk脚本,它从两个文件夹中选择相同的文件集并读取其中的内容。 如果两个文件中的所有记录都相同,则应继续处理下一组文件,或者如果任何记录中存在差异,则应仅将该记录重定向到另一个文件名,例如$filename_diff。 我是bash和awk的新学员,经过多次尝试,我只能编写以下根本不运行的代码:( 请帮助提供解决方案。 提前非常感谢。我会这样做: #!/b

我在Linux服务器中有两个diff目录,其中来自两个diff服务器的.csv文件不断出现。两个目录中文件的文件名相同。 我想要一个bash/awk脚本,它从两个文件夹中选择相同的文件集并读取其中的内容。 如果两个文件中的所有记录都相同,则应继续处理下一组文件,或者如果任何记录中存在差异,则应仅将该记录重定向到另一个文件名,例如$filename_diff。 我是bash和awk的新学员,经过多次尝试,我只能编写以下根本不运行的代码:(

请帮助提供解决方案。
提前非常感谢。

我会这样做:

#!/bin/sh
for file1 in /var/opt/dir1/*.csv
do
    name1=$(basename "$file1")
    file2="/var/opt/dir2/$name1"
    [ -f "$file2" ] || continue
    cmp -s "$file1" "$file2" && continue
    diff "$file1" "$file2" | sed -e '/^[^>]/d' -e 's/^> //' >/var/opt/diff/"${name1}_diff`
done
就是

  • 不要使用“ls”获取文件名列表
  • 只需要一个循环
  • diff
    程序可以(如注释中所述)通过从默认输出中选择“>”行来提供所需的信息
  • 为输出文件名指定的路径名似乎不正确(我删除了不需要的目录部分)

@init_js:-您建议的更改对我很有效。下面是工作脚本

#!/bin/bash

for file1 in /var/opt/dir1/*.csv
do
file2=/var/opt/dir2/$(basename "$file1")
if [[ -e "$file2" ]]
then
awk 'BEGIN {FS==","} NR == FNR{arr[$0];next} ! ($0 in arr)' $file1 $file2 > /var/opt/diff/`echo $(basename "$file1")_diff`
fi
done

我不明白一件事,为什么“file2”变量没有声明为file2=$(/var/opt/dir2/$(basename“$file1”);因为通常我们用$(命令)声明变量仅此而已,不是吗?

有几个地方是错误的。对于/var/opt/dir1/*.csv中的文件1,在第一个for循环中使用简单的glob扩展
;do…done
。只有当文件具有相同的基名时,才比较它们。因此,基于第一个文件名形成第二个文件名:
文件2=/var/opt/dir2/$(基名“$file1”)
。您可以将两个字符串与
进行比较[[
使用
=
,而不是
=
(您将
=
/bin/[
)一起使用。并且您要确保
$file2
存在于:
如果[-e“$file2”]];
您不应该使用
/usr/bin/diff
来比较内容吗?您真正想要实现的是什么?()如果您想比较两个目录的内容,为什么
diff--recursive dir1 dir2
不够?嗨,Micha,谢谢你的回复…我不能使用diff,因为虽然它会显示不同的文件,但不会告诉我该文件中的特定记录不同(因为我在一个文件中有数千条记录),另外,不同记录的重定向在diff中也是一个挑战…嘿,init_js,也谢谢你的回复…请让我按照你的建议检查并制定脚本。我会给你回复的。你说的“哪个记录”是什么意思?
diff
显示两个文件中不同的行以及行号。如果需要,可以选择从前一行提取上下文。您可能还需要什么?
#!/bin/bash

for file1 in /var/opt/dir1/*.csv
do
file2=/var/opt/dir2/$(basename "$file1")
if [[ -e "$file2" ]]
then
awk 'BEGIN {FS==","} NR == FNR{arr[$0];next} ! ($0 in arr)' $file1 $file2 > /var/opt/diff/`echo $(basename "$file1")_diff`
fi
done