我正在编写一个shell脚本,并且为了使它更简单易读,我试图使用嵌套的子shell将参数传递给diff.
这就是我所拥有的:
if
diff -iy '$(sort '$(awk 'BEGIN { FS = "|" } ; {print $1}' new-participants-by-state.csv)' '$(awk 'BEGIN { FS = "|" } ; {print $1}' current-participants-by-state.csv)')' > /dev/null;
then
echo There is no difference between the files. > ./participants-by-state-results.txt;
else
diff -iy '$(sort '$(awk 'BEGIN { FS = "|" } ; {print $1}' new-participants-by-state.csv)' '$(awk 'BEGIN { FS = "|" } ; {print $1}' current-participants-by-state.csv)')' > ./participants-by-state-results.txt;
fi
Run Code Online (Sandbox Code Playgroud)
当我运行脚本时,我会继续 diff: extra operand 'AL'
我很欣赏任何有关为什么失败的见解.我觉得我很亲密.谢谢!
你的代码是不可读的,因为这些行很长:
if diff -iy '$(sort '$(awk 'BEGIN { FS = "|" } ; {print $1}' new-participants-by-state.csv)' \
'$(awk 'BEGIN { FS = "|" } ; {print $1}' current-participants-by-state.csv)')' \
> /dev/null;
then
echo There is no difference between the files. > ./participants-by-state-results.txt;
else
diff -iy '$(sort '$(awk 'BEGIN { FS = "|" } ; {print $1}' new-participants-by-state.csv)' \
'$(awk 'BEGIN { FS = "|" } ; {print $1}' current-participants-by-state.csv)')' \
> ./participants-by-state-results.txt;
fi
Run Code Online (Sandbox Code Playgroud)
重复这样的整个命令也是相当讨厌的.您使用单引号也存在重大问题; 你在每组命令中只有一种,显然是在两个相同awk命令的组合输出上运行(而你可能需要两个独立的排序,一个用于每个awk命令的输出); 你什么时候没有使用这个-F选项awk; 你正在重复这个地方庞大的文件名; 最后,看起来你可能想要使用进程替换,但实际上并没有这样做.
让我们退后一步,明确地提出问题.
new-participants-by-state.csv和current-participants-by-state.csv)在每个文件的每一行上找到第一个管道分隔字段,对这些字段的列表进行排序,并比较两个排序列表的结果.participants-by-state-results.txt; 否则,列出输出文件中的差异.所以,我们可以使用:
oldfile='current-participants-by-state.csv'
newfile='new-participants-by-state.csv'
outfile='participants-by-state-results.txt'
tmpfile=${TMPDIR:-/tmp}/xx.$$
awk -F'|' '{print $1}' $oldfile | sort > $tmpfile.1
awk -F'|' '{print $1}' $newfile | sort > $tmpfile.2
if diff -iy $tmpfile.1 $tmpfile.2 > $outfile
then echo "There is no difference between the files" > $outfile
fi
rm -f $tmpfile.?
Run Code Online (Sandbox Code Playgroud)
如果这将是最终的脚本,我们希望将陷阱处理放在适当的位置,以便除非脚本被SIGKILL杀死,否则不会留下临时文件.
但是,我们现在可以使用进程替换来避免临时文件:
oldfile='current-participants-by-state.csv'
newfile='new-participants-by-state.csv'
outfile='participants-by-state-results.txt'
if diff -iy <(awk -F'|' '{print $1}' $oldfile | sort) \
<(awk -F'|' '{print $1}' $newfile | sort) > $outfile
then echo "There is no difference between the files" > $outfile
fi
Run Code Online (Sandbox Code Playgroud)
请注意代码如何在存在对称性的情况下仔细保留对称性.请注意使用短变量名称以避免重复长文件名.请注意,该diff命令只运行一次,而不是两次 - 丢弃以后需要的结果不是很明智.
您可以使用以下方法压缩输出I/O重定向:
{
if diff -iy <(awk -F'|' '{print $1}' $oldfile | sort) \
<(awk -F'|' '{print $1}' $newfile | sort)
then echo "There is no difference between the files"
fi
} > $outfile
Run Code Online (Sandbox Code Playgroud)
这会将附带命令的标准输出发送到文件.
当然,如果文件是以管道分隔而不是以逗号分隔的,则CSV可能不是合适的术语,但这完全是另一回事.
我也假设diff -iy原始脚本建议的状态是起作用的; 我没有验证该diff命令的用法.
| 归档时间: |
|
| 查看次数: |
1504 次 |
| 最近记录: |