检查文件中的行是否具有相同的列数
checking that the rows in a file have the same number of columns
我有很多 tsv 文件,我想检查每个文件的格式是否正确。主要是,我想检查每一行的列数是否正确。有没有办法做到这一点?如果有的话,我会喜欢命令行解决方案。
(我假设 "tsv" 是指一个文件,其列由制表符分隔。)
只要文件中没有包含制表符的引用字段,您就可以使用 awk 轻松完成此操作。
如果您知道期望的列数,则以下方法可行:
awk -F '\t' -v NCOLS=42 'NF!=NCOLS{printf "Wrong number of columns at line %d\n", NR}'
(当然,你需要把42
改成正确的值。)
您还可以从第一行自动获取列数:
awk -F '\t' 'NR==1{NCOLS=NF};NF!=NCOLS{printf "Wrong number of columns at line %d\n", NR}'
如果第一行的列数错误,那将起作用(有很多噪音),但它将无法检测到 所有 行具有的文件同样错误的列数。所以你可能最好使用第一个版本,它强制你指定列数。
awk '{print NF}' test | sort -nu | head -n 1
这为您提供文件中任何给定行的最少列数。
awk '{print NF}' test | sort -nu | tail -n 1
这为您提供了文件中任何给定行的最大列数。
如果所有列都存在,结果应该是相同的。
注意:这让我在 OS X 上出现错误,但在 Debian 上却没有...也许使用 gawk
.
awk
是一个很好的选择。如果您的列由制表符分隔(我猜这是 tsv
的意思)并且如果您知道应该有多少列,比如 17,您可以尝试:
awk -F'\t' 'NF != 17 {print}' file.tsv
这将打印 file.tsv
中没有完全用制表符分隔的 17 列的所有行。如果我的猜测不正确,请编辑您的问题并添加缺失的信息(列分隔符、列数...)请注意 tsv
(和 csv
)格式比看起来更棘手。字段可以包含字段分隔符,记录可以跨越多行...如果是您的情况,请不要尝试重新发明轮子并使用现有的 tsv
解析器。
只是清理@snd 上面的回答:
number_uniq_row_lengths=`awk '{print NF}' $pclFile | sort -nu | wc -l`
if [ $number_uniq_row_lengths -eq 1 ] 2>/dev/null; then
echo "$pclFile is clean"
fi
在这里添加这个是因为这些答案都很接近但对我来说不太适用,在我的情况下我需要为 awk 指定字段分隔符。
以下内容应 return 在一行中包含列数(如果每行的列数相同)。
$ awk -F'\t' '{print NF}' test.tsv | sort -nu
8
- -F用于指定awk的字段分隔符
- NF是字段数
- -nu 按数字对每一行的字段计数进行排序,return 仅对唯一的字段进行排序
如果您得到不止一行 returned,那么您的 .tsv 中有些行的列数比其他行多。
要检查 .tsv 格式是否正确,每行的字段数相同,以下内容应 return 1(正如 kmace 在接受的答案中评论的那样)但是我需要添加 - F'\t'
$ awk -F'\t' '{print NF}' test.tsv | sort -nu | wc -l
我有很多 tsv 文件,我想检查每个文件的格式是否正确。主要是,我想检查每一行的列数是否正确。有没有办法做到这一点?如果有的话,我会喜欢命令行解决方案。
(我假设 "tsv" 是指一个文件,其列由制表符分隔。)
只要文件中没有包含制表符的引用字段,您就可以使用 awk 轻松完成此操作。
如果您知道期望的列数,则以下方法可行:
awk -F '\t' -v NCOLS=42 'NF!=NCOLS{printf "Wrong number of columns at line %d\n", NR}'
(当然,你需要把42
改成正确的值。)
您还可以从第一行自动获取列数:
awk -F '\t' 'NR==1{NCOLS=NF};NF!=NCOLS{printf "Wrong number of columns at line %d\n", NR}'
如果第一行的列数错误,那将起作用(有很多噪音),但它将无法检测到 所有 行具有的文件同样错误的列数。所以你可能最好使用第一个版本,它强制你指定列数。
awk '{print NF}' test | sort -nu | head -n 1
这为您提供文件中任何给定行的最少列数。
awk '{print NF}' test | sort -nu | tail -n 1
这为您提供了文件中任何给定行的最大列数。 如果所有列都存在,结果应该是相同的。
注意:这让我在 OS X 上出现错误,但在 Debian 上却没有...也许使用 gawk
.
awk
是一个很好的选择。如果您的列由制表符分隔(我猜这是 tsv
的意思)并且如果您知道应该有多少列,比如 17,您可以尝试:
awk -F'\t' 'NF != 17 {print}' file.tsv
这将打印 file.tsv
中没有完全用制表符分隔的 17 列的所有行。如果我的猜测不正确,请编辑您的问题并添加缺失的信息(列分隔符、列数...)请注意 tsv
(和 csv
)格式比看起来更棘手。字段可以包含字段分隔符,记录可以跨越多行...如果是您的情况,请不要尝试重新发明轮子并使用现有的 tsv
解析器。
只是清理@snd 上面的回答:
number_uniq_row_lengths=`awk '{print NF}' $pclFile | sort -nu | wc -l`
if [ $number_uniq_row_lengths -eq 1 ] 2>/dev/null; then
echo "$pclFile is clean"
fi
在这里添加这个是因为这些答案都很接近但对我来说不太适用,在我的情况下我需要为 awk 指定字段分隔符。
以下内容应 return 在一行中包含列数(如果每行的列数相同)。
$ awk -F'\t' '{print NF}' test.tsv | sort -nu
8
- -F用于指定awk的字段分隔符
- NF是字段数
- -nu 按数字对每一行的字段计数进行排序,return 仅对唯一的字段进行排序
如果您得到不止一行 returned,那么您的 .tsv 中有些行的列数比其他行多。
要检查 .tsv 格式是否正确,每行的字段数相同,以下内容应 return 1(正如 kmace 在接受的答案中评论的那样)但是我需要添加 - F'\t'
$ awk -F'\t' '{print NF}' test.tsv | sort -nu | wc -l