File1 - filename.csv
File2 - filename.csv
我想使用 ksh 脚本比较 Linux 中这两个文件之间的标头。
情况1:-
比如说,file1的头是INPUT -->
NAME,UNIT CODE, VAR
JAMES01,IPU UNIT,OTHER
FIERCY,AUTOIMMUNE,OTHER
file2的头是INPUT -->
输出:- 这两个文件之间的标头匹配
案例2:-
假设 file1 的标头是 INPUT --> plant,animal,object file2 的标头是 INPUT --> plant,animal,object,tree
输出 - 有一个多余的列,EXCESS COLUMN NAME IS 'tree'
仅供参考 - 请注意标头是从 csv 文件中获取的,而不是硬编码的。非常感谢!
答案1
最简单的方法就是比较每个文件的第一行,然后根据它们是否相同移动到正确的目录:
$ diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv)
Files /dev/fd/63 and /dev/fd/62 differ
然后,您可以根据结果使用&&
(和)和||
(或)运算符对文件执行不同的操作。例如,如果file2.csv
具有相同的标头,则将其移动到名为 的目录same
,如果不同,则移动到名为 的目录different
:
$ mkdir -p same different
$ diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv) &&
mv file2.csv same/ || mv file2.cxv different/
如果您确实需要知道不同的特定字段,并且可以确定差异始终是最后一个字段,您可以这样做:
diff -qs <(head -n1 file1.csv) <(head -n1 file2.csv) >/dev/null &&
echo "The headers are the same" ||
echo "file2.csv has an extra entry: $(awk -F, '{ print $NF; exit}' file2.csv)"
如果您需要处理任何区别,使用:
awk -F, 'BEGIN{ FS=OFS="," }
{
if(NR==FNR){
for(i=1; i<=NF; i++){ a[$i]++ }
}
else{
for(i=1; i<=NF; i++){
if (! ($i in a)){
b[$i]++
}
}
}
}
END{
printf "The second file has extra fields: ";
for( field in b){
printf "\"%s\" ", field
}
}' file1.csv file2.csv
答案2
这可能是您想要做的,未经测试并使用支持的 awk nextfile
,例如 GNU awk:
awk '
BEGIN { FS="," }
FILENAME == ARGV[1] {
nf = split($0,a)
nextfile
}
FILENAME == ARGV[2] {
nf = (NF > nf ? NF : nf)
for ( i=1; i<=nf; i++ ) {
if ( $i"" != a[i]"" ) {
printf "Field %d difference: %s \"%s\" != %s \"%s\"\n", i, ARGV[1], a[i], FILENAME, $i
}
}
exit
}
' file1.csv file2.csv
如果你的 awk 不支持nextfile
,请更改:
FILENAME == ARGV[1] {
nf = split($0,a)
nextfile
}
对此:
FILENAME == ARGV[1] {
if ( NR == 1 ) {
nf = split($0,a)
}
next
}
它仍然可以工作,只是运行速度较慢,因为它必须读取整个第一个文件,而不仅仅是它的第一行。
上面假设第二个文件不为空。如果可以,则在该FILENAME == ARGV[2]
位置填充第二个数组,然后在该END
部分中比较它们。