Bash:将空列添加到位置未知的CSV

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我会这样做:

目前,我们收到多个大型CSV文件,需要将其插入/更新到数据库中。 我们数据库的模式没有改变。 我们只需要标题数据库中指定的特定顺序的特定列。这些可能在任何给定点发生变化。我们收到的CSV文件也可以随时按顺序更改

因此,我所做的是将所需的列从头数据库传输到这个脚本$TEMP_文件中,并从收到的CSV$REC_CSV中提取所需的列

到目前为止,这一切都很顺利:

awk'NR==FNR{ Clm=Clm Clm?|:1美元 下一个 } FNR==1{ 对于i=1;i=2{
对于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