Bash:将空列添加到位置未知的CSV
目前,我们收到多个大型CSV文件,需要将其插入/更新到数据库中。 我们数据库的模式没有改变。 我们只需要标题数据库中指定的特定顺序的特定列。这些可能在任何给定点发生变化。我们收到的CSV文件也可以随时按顺序更改 因此,我所做的是将所需的列从头数据库传输到这个脚本$TEMP_文件中,并从收到的CSV$REC_CSV中提取所需的列 到目前为止,这一切都很顺利: awk'NR==FNR{ Clm=Clm Clm?|:1美元 下一个 } FNR==1{ 对于i=1;i=2{Bash:将空列添加到位置未知的CSV,csv,awk,Csv,Awk,目前,我们收到多个大型CSV文件,需要将其插入/更新到数据库中。 我们数据库的模式没有改变。 我们只需要标题数据库中指定的特定顺序的特定列。这些可能在任何给定点发生变化。我们收到的CSV文件也可以随时按顺序更改 因此,我所做的是将所需的列从头数据库传输到这个脚本$TEMP_文件中,并从收到的CSV$REC_CSV中提取所需的列 到目前为止,这一切都很顺利: awk'NR==FNR{ Clm=Clm Clm?|:1美元 下一个 } FNR==1{ 对于i=1;i=2{ 对于i=1;i我会这样做:
对于i=1;i我会这样做:
awk -F\| -v outHeader="$(< "$TEMP_FILE")" '
NR == 1 {
for (i = 1; i <= NF; ++i)
inTitleToIdx[$i] = i
idxEmptyField = NF+1000
maxOutIdx = split(outHeader, outIdxToTitle)
for (i = 1; i <= maxOutIdx; ++i) {
inIdx = inTitleToIdx[outIdxToTitle[i]]
outIdxToInIdx[i] = inIdx == "" ? idxEmptyField : inIdx
}
print outHeader
}
NR > 1 {
sep=""
for (i = 1; i <= maxOutIdx; ++i) {
printf "%s%s", sep, $outIdxToInIdx[i]
sep = FS
}
print ""
}
' inputFile
注意:您不需要临时文件$TEMP_file。您也可以编写-v outHeader=id | anotherId | hahahaIdontExist | timestamp或-v outHeader=$commandthattreadtheheaderfromthedb。对于显示的示例,您可以尝试以下内容。用GNU awk编写并测试
非常感谢!近乎完美的解决方案:必须匿名化许多组件,但一般方法是完美的!@AtroCty很高兴听到这一点。尽管我注意到这有点效率低下。在旧版本中,输入文件中的所有字段都存储在一个数组中,即使其中一些字段根本没有打印。我将此答案更改为新版本n哪个应该更有效。您仍然可以通过检查此答案的
id|timestamp|anotherId|thisId|andThisId|andAnotherId
1|2:00|34|44|44|41
2|2:00|34|45|44|41
3|3:00|35|46|44|41
id|anotherId|timestamp
1|34|2:00
2|34|2:00
3|35|3:00
id|anotherId|hahahaIdontExist|timestamp
1|34||2:00
2|34||2:00
3|35||3:00
awk -F\| -v outHeader="$(< "$TEMP_FILE")" '
NR == 1 {
for (i = 1; i <= NF; ++i)
inTitleToIdx[$i] = i
idxEmptyField = NF+1000
maxOutIdx = split(outHeader, outIdxToTitle)
for (i = 1; i <= maxOutIdx; ++i) {
inIdx = inTitleToIdx[outIdxToTitle[i]]
outIdxToInIdx[i] = inIdx == "" ? idxEmptyField : inIdx
}
print outHeader
}
NR > 1 {
sep=""
for (i = 1; i <= maxOutIdx; ++i) {
printf "%s%s", sep, $outIdxToInIdx[i]
sep = FS
}
print ""
}
' inputFile
awk '
BEGIN{
FS=OFS="|"
}
FNR==NR{
for(i=1;i<=NF;i++){
arr[$i]=i
}
print
next
}
FNR==1{
PROCINFO["sorted_in"] = "@val_num_asc"
num=split($0,currVal,"|")
for(k=1;k<=num;k++){
currVal1[currVal[k]]=k
}
for(u in arr){
if(u in currVal1){
realArr[++count]=currVal1[u]
delete arr[u]
}
else{
realArr[++count]="NA"
}
}
next
}
{
for(k=1;k<=count;k++){
printf("%s%s",(realArr[k]!="NA"?$realArr[k]:OFS),(k==count?ORS:realArr[k]!="NA"?OFS:""))
}
}
' temp_file input.csv
id|anotherId|hahahaIdontExist|timestamp
1|34||2:00
2|34||2:00
3|35||3:00