【发布时间】:2021-09-02 23:52:57
【问题描述】:
我正在 BASH shell 脚本中编写一个函数,它应该从带有标题的 csv 文件返回行,逗号比标题多。这可能会发生,因为这些文件中有可能包含逗号的值。为了质量控制,我必须识别这些线以便以后清理它们。我目前拥有的:
#!/bin/bash
get_bad_lines () {
local correct_no_of_commas=$(head -n 1 $1/$1_0_0_0.csv | tr -cd , | wc -c)
local no_of_files=$(ls $1 | wc -l)
for i in $(seq 0 $(( ${no_of_files}-1 )))
do
# Check that the file exist
if [ ! -f "$1/$1_0_${i}_0.csv" ]; then
echo "File: $1_0_${i}_0.csv not found!"
continue
fi
# Search for error-lines inside the file and print them out
echo "$1_0_${i}_0.csv has over $correct_no_of_commas commas in the following lines:"
grep -o -n '[,]' "$1/$1_0_${i}_0.csv" | cut -d : -f 1 | uniq -c | awk '$1 > $correct_no_of_commas {print}'
done
}
get_bad_lines products
get_bad_lines users
这个程序的输出现在是所有文件中所有行号的所有逗号计数,
我怀疑这是由于输入$1(文件夹名,即产品和用户)与参考$1 的awk 的调用冲突(我希望获取第一列是逗号的计数)循环中当前文件中的那一行)。
这是问题吗?如果是这样,是否可以通过使用不同的变量名而不是使用$1 引用第一列或文件夹名称来解决?
示例,当前输出:
5 6667
5 6668
5 6669
5 6670
(应该只显示包含超过 5 个逗号的文件的行)。
在 awk 调用中也尝试了变量声明,效果相同 (如Awk field variable clash with function argument 接受的答案) :
get_bad_lines () {
local table_name=$1
local correct_no_of_commas=$(head -n 1 $table_name/${table_name}_0_0_0.csv | tr -cd , | wc -c)
local no_of_files=$(ls $table_name | wc -l)
for i in $(seq 0 $(( ${no_of_files}-1 )))
do
# Check that the file exist
if [ ! -f "$table_name/${table_name}_0_${i}_0.csv" ]; then
echo "File: ${table_name}_0_${i}_0.csv not found!"
continue
fi
# Search for error-lines inside the file and print them out
echo "${table_name}_0_${i}_0.csv has over $correct_no_of_commas commas in the following lines:"
grep -o -n '[,]' "$table_name/${table_name}_0_${i}_0.csv" | cut -d : -f 1 | uniq -c | awk -v table_name="$table_name" '$1 > $correct_no_of_commas {print}'
done
}
【问题讨论】:
-
谢谢,@Zilog80。我有点不清楚:CSV 文件中的值不包含引号,但单个值可能包含一个或多个逗号。如果没有人工检查,很难知道哪个值对应哪个字段。
-
在格式正确的 CSV 文件中,字段内的逗号(或换行符)不是问题,因为 CSV 格式为此类情况提供了引用规则,它们应该不会造成任何麻烦。例如,CSV 行
FOO,"BAR,BAZ",BOOM有 3 个字段,第二个字段是 BAR,BAZ。 -
@user1934428 ,你是对的。不幸的是,我收到格式不正确的 CSV 文件,没有引号,例如
FOO,BAR,BAZ,BOOM,其中BAR,BAZ对应单个字段 -
@GustavRasmussen:如果您知道此类字段的格式总是不正确,您可以简单地计算行中的逗号并选择那些数字不正确的行。如果某些行可能格式不正确,而其他行的逗号字段格式正确,则 IMO 最简单的方法是使用 CSV 解析器。
-
grep -o -n '[,]'命令将为您期望该行中所有匹配逗号的每一行返回第一个逗号匹配。由于您需要严格计算逗号的数量,您应该将awk与awk -v table_name="$table_name" -v num_comma=$correct_no_of_commas '/,/ {if (gsub(/,/, ",")>num_comma) print($0);}' "$table_name/${table_name}_0_${i}_0.csv"结合起来。如果文件遇到不正确的逗号数,您也可以签入awk脚本,然后仅输出相关文件。
标签: linux string bash function awk