使用 awk 命令从 csv 读取和打印第一 1000 行,然后再打印 1000 行,依此类推
Posted
技术标签:
【中文标题】使用 awk 命令从 csv 读取和打印第一 1000 行,然后再打印 1000 行,依此类推【英文标题】:To read and print 1st 1000 rows from a csv using awk command and then next 1000 and so on 【发布时间】:2022-01-18 15:49:36 【问题描述】:我有一个大约 25k 行的 csv。我必须一次从第 1 列和第 2 列中选择 1000 行,然后再选择下 1000 行,依此类推。
我正在使用下面的命令,它可以很好地从列#1 和列#2 中提取所有值,即从两列中提取 25K 字段,我想选择 1-1000 之类的值,将它们放入我的 sql导出查询然后 1001-2000,2001-3000 等等,然后将值放在我的导出查询中的 WHERE IN 中,并将结果附加到 dbData.csv 文件中。
我的代码如下:
awk -F ',' 'NR > 2 print $1' $INPUT > column1.txt
i=$(cat column1.txt | sed -n -e 'H;$x;s/\n/,/g;s/^,//;p;')
awk -F ',' 'NR > 2 print $2' $INPUT > column2.txt
j=$(cat column2.txt | sed -n -e 'H;$x;s/\n/,/g;s/^,//;p;')
echo "Please wait - connecting to database..."
db2 connect to $sourceDBStr user user123 using pas123
db2 "export to dbData.csv of del select partnumber,language_id as LanguageId from CATENTRY c , CATENTDESC cd where c.CATENTRY_ID=cd.CATENTRY_ID and c.PARTNUMBER in ($i) and cd.language_id in ($j)"
【问题讨论】:
欢迎来到 SO,感谢您分享您的努力。请务必提及当您获取前 1000 行等时您正在尝试做什么?您的目标是运行命令还是打印一些东西?请在您的问题中添加更多详细信息,以便我们尝试帮助您,干杯。 edit 您的问题要包括该信息和所有其他信息,请勿将其放在无法格式化且容易遗漏的 cmets 中。此外,您在使用 awk 时永远不需要 sed,因此请确保向我们展示您想要的最终输出格式,而不是您当前认为需要运行 sed 的格式。一定要显示一个minimal reproducible example,例如每 3 行而不是 1000 行。awk 'print $1' CatalogEntriesDescription.csv | split -l 1000
?
这能回答你的问题吗? How can I split a large text file into smaller files with an equal number of lines?
您添加了代码,但仍然没有示例输入和预期输出,因此到目前为止您已经提供了我们要求您提供的三分之一,因此我们可以为您提供帮助。正如我在my first comment above 中提到的,一定要展示一个minimal reproducible example,其中包含简洁、可测试的样本输入和预期输出,例如例如,一个 10 行长的文件,例如,每 3 行而不是 1000 行被拆分。
【参考方案1】:
假设您的输入 CSV 的前两个字段是 "simple"(没有空格,没有逗号...)并且不需要任何类型的引用。您可以使用 awk
脚本生成查询字符串的棘手部分:
# foo.awk
NR >= first && NR <= last
c1[n+0] = $1
c2[n++] = $2
END
for(i = 0; i < n-1; i++) printf("%s,", c1[i])
printf("%s) %s (%s", c1[n-1], midstr, c2[0])
for(i = 1; i < n; i++) printf(",%s", c2[i])
然后在bash
循环中使用它来处理每次迭代的 1000 条记录,将查询结果存储在一个临时文件中(例如,tmp.csv
在下面的bash
脚本中),你可以连接到你的@ 987654326@ 文件。以下示例bash
脚本使用与您相同的参数(INPUT
、sourceDBStr
)和相同的常量(dbData.csv
、1000
、user123
、pas123
)。如果您需要更大的灵活性,请进行调整。错误管理(未找到输入文件、DB 连接错误、DB 查询错误...)留作bash
练习(但应该完成)。
prefix="export to tmp.csv of del select partnumber,language_id as LanguageId from CATENTRY c , CATENTDESC cd where c.CATENTRY_ID=cd.CATENTRY_ID and c.PARTNUMBER in"
midstr="and cd.language_id in"
rm -f dbData.csv
len=$(cat "$INPUT" | wc -l)
for (( first = 2; first <= len - 999; first += 1000 )); do
(( last = len < first + 999 ? len : first + 999 ))
query=$(awk -F ',' -f foo.awk -v midstr="$midstr" -v first="$first" \
-v last="$last" "$INPUT")
echo "Please wait - connecting to database..."
db2 connect to $sourceDBStr user user123 using pas123
db2 "$prefix ($query)"
cat tmp.csv >> dbData.csv
done
rm -f tmp.csv
但还有其他方法可以使用 split
、bash
数组和更简单的 awk
或 sed
脚本。示例:
declare -a arr=()
prefix="export to tmp.csv of del select partnumber,language_id as LanguageId from CATENTRY c , CATENTDESC cd where c.CATENTRY_ID=cd.CATENTRY_ID and c.PARTNUMBER in"
midstr="and cd.language_id in"
awk -F, 'NR>1 print $1, $2' "$INPUT" | split -l 1000 - foobar
rm -f dbData.csv
for f in foobar*; do
arr=($(awk 'print $1 ","' "$f"))
i="$arr[*]"
arr=($(awk 'print $2 ","' "$f"))
j="$arr[*]"
echo "Please wait - connecting to database..."
db2 connect to $sourceDBStr user user123 using pas123
db2 "$prefix ($i%,) $midstr ($j%,)"
cat tmp.csv >> dbData.csv
rm -f "$f"
done
rm -f tmp.csv
【讨论】:
以上是关于使用 awk 命令从 csv 读取和打印第一 1000 行,然后再打印 1000 行,依此类推的主要内容,如果未能解决你的问题,请参考以下文章
我正在使用awk命令,但无法使用shell脚本在列中打印IP