linux 如何验证所有csv文件的第一行是否相同?[已关闭]

2wnc66cl  于 2023-04-05  发布在  Linux
关注(0)|答案(5)|浏览(116)

已关闭,此问题需要更focused,目前不接受回答。
**想要改进此问题吗?**更新此问题,使其仅关注editing this post的一个问题。

12小时前关门了。
截至12小时前,社区正在审查是否重新讨论这个问题。
Improve this question
我有一个包含许多csv文件的目录。我希望一个shell脚本检查每个文件的第一行是否相同。例如,这些文件具有相同的头,因此检查应返回True。

❯ cat file1.csv
column1,column2,column3
3,1,3
4,3,9
❯ cat file2.csv
column1,column2,column3
5,4,1
1,8,2

我以为这是一个已经提出的问题,但我还没有在Stackoverflow上看到它。
这个问题类似,它检查一个文件中的所有行是否相同:https://unix.stackexchange.com/questions/533915/check-if-all-lines-in-a-file-are-same .
我尝试过的:

  • echo "$(ls -AU | head -1)"获取文件的第一行
  • 我曾想过尝试Assert所有文件的第一行都有这个值(最好是一个简洁的管道,而不是for循环),但不知道如何做到这一点
  • 我尝试在这里使用答案https://unix.stackexchange.com/a/533917,它使用uniqwc,但这两个命令似乎都是特定于遍历单个文件的行(而不是遍历一般的列表输出)。
7gs2gvoe

7gs2gvoe1#

使用GNU sedbash

rows=$(sed -s '1!d' *.csv | sort -u | wc -l)
if [[ "$rows" -eq 1 ]]; then echo "true"; else echo "false"; fi

sed -s '1!d' *.csv输出到stdout当前目录中所有文件的第一行,后缀为.csv

r6vfmomb

r6vfmomb2#

一个awk的想法:

awk '
    { headers[$0]; nextfile }             # use 1st line as array index; skip to next file
END { if ( length(headers)==1 )           # if array only has one entry then ...
         print "true"                     # all files have the same header line
      else                                # else ...
         print "false"                    # there is more than one unique header
    }
' *.csv
euoag5mw

euoag5mw3#

这有助于了解哪个文件是不同的。
给定:

head -n 2 *.csv
==> file1.csv <==
column1,column2,column3
3,1,3

==> file2.csv <==
column1,column2,column3
5,4,1

==> file3.csv <==
column_diff,column2,column3
5,4,1

==> file4.csv <==
column1,column2,column3
5,4,1

您可以使用此Ruby来确定罪犯:

ruby -e 'keys=ARGV.each_with_object(Hash.new {|h,k| h[k] = []}){|fn,h| 
    h[File.open(fn).readline.chomp]<<fn
}
keys.each{|k,v| puts "#{k}\n\t#{v.join("\n\t")}"}
' *.csv

图纸:

column1,column2,column3
    file1.csv
    file2.csv
    file4.csv
column_diff,column2,column3
    file3.csv

如果你想从Bash测试结果:

ruby -e 'keys=ARGV.each_with_object(Hash.new {|h,k| h[k] = []}){|fn,h| 
    h[File.open(fn).readline.chomp]<<fn
}
if keys.length>1 then
    keys.each{|k,v| puts "#{k}\n\t#{v.join("\n\t")}"}
    exit(false)
else
    puts "All files equal"
end
' *.csv

然后测试退出代码。

zf9nrax1

zf9nrax14#

使用任何awk(未测试):

awk '
    FNR == 1 {
        if ( $0 != prev ) {
            status = 1
            exit
        }
        prev = $0
        nextfile
    }
    END {
        print ( status ? "false" : "true" )
        exit status
    }
' *.csv

如果你的awk支持nextfile,它会运行得更快,但无论哪种方式都可以工作。
我在上面假设您希望脚本打印“true”/“false”并以成功/失败状态退出。

jhiyze9q

jhiyze9q5#

使用GNU head(对于-q选项),这个一行程序应该可以做到:

if [ -z "$(head -q -n1 *.csv | uniq -u)" ]; then echo true; else echo false; fi

GNU head-q选项将抑制文件名的打印。uniq -u仅在所有行都相同时给予输出。sort对于此任务不是必需的。

相关问题