【问题标题】:insert quotes for each field using awk [duplicate]使用 awk 为每个字段插入引号 [重复]
【发布时间】:2019-12-30 11:59:58
【问题描述】:

我正在根据下面提供的示例寻找以下输入

示例:

eno~ename~address~zip
123~abc~~560000~"a~b~c"
245~"abc ~ def"~hyd~560102
333~"ghi~jkl"~pub~560103

预期输出:

"eno"~"ename"~"address"~"zip"
"123"~"abc"~""~"560000"~"a~b~c"
"245"~"abc ~ def"~"hyd"~"560102"
"333"~"ghi~jkl"~"pub"~"560103"

如果分隔符值包含在数据中,我在 awk 中尝试过的命令不起作用。如果有 perl/sed/awk 的任何替代建议建议。

下面是命令: awk '{for (i=1;i

【问题讨论】:

标签: perl awk sed


【解决方案1】:

您能否尝试以下操作(仅使用提供的样本进行测试)。

awk 'BEGIN{s1="\"";FS=OFS="~"} {for(i=1;i<=NF;i++){if($i!~/^\"|\"$/){$i=s1 $i s1}}} 1' Input_file

输出如下。

"eno"~"ename"~"address"~"zip"
"123"~"abc"~""~"560000"
"245"~"abc ~ def"~"hyd"~"560102"
"333"~"ghi~jkl"~"pub"~"560103"

说明:现在为上述代码添加说明。

awk '                       ##Starting awk program here.
BEGIN{                      ##Starting BEGIN section of awk program here.
  s1="\""                   ##Setting variable s1 to " here.
  FS=OFS="~"                ##Setting value of FS and OFS as ~ here.
}                           ##Closing BEGIN block of awk code here.
{
  for(i=1;i<=NF;i++){       ##Starting for loop here from i=1 to till value of NF here.
    if($i!~/^\"|\"$/){      ##Checking condition of value of current field is NOT having s1 value in it.
      $i=s1 $i s1           ##Adding s1 variable before and after the value of $i.
    }                       ##Closing block for if condition.
  }                         ##Closing block for for loop here.
}                           ##Closing main block here.
1                           ##Mentioning 1 will print the lines of Input_file.
'  Input_file               ##mentioning Input_file name here.


【讨论】:

  • 如果有"a~b~c"这样的字段呢?
  • @oguzismail,好吧没考虑,因为它不在 OP 的样本中,让我现在修复它。
  • 我不会修复它,这显然是重复的。请参阅我对这个问题的评论。赞成,因为逻辑很聪明
  • 123~abc~~560000"a~b~c" 这不应该是一个有效的输入,因为你只在字段周围使用双引号,而不是在字段内,并且由于 ~ 用作 FS,560000"a~b~c" 这部分会中断全部。正确的应该是560000~"a~b~c"
  • 它认为最好测试字段是否不以双引号if($i!~/^\"/)开头,不包含双引号。 if($i !~ s1)
【解决方案2】:

在这里您可以使用FPATgnu awk

awk -v FPAT='([^~]*)|("[^"]+")' -v OFS="~" '{for (i=1;i<=NF;i++) if ($i!~/^\"/) $i="\""$i"\""} 1' file
"eno"~"ename"~"address"~"zip"
"123"~"abc"~""~"560000"
"245"~"abc ~ def"~"hyd"~"560102"
"333"~"ghi~jkl"~"pub"~"560103"

我们不告诉字段分隔符的样子,而是告诉字段的样子。然后测试字段是否没有双引号,如果没有,添加它。

然后,您可以根据需要轻松更改字段分隔符:

awk -v FPAT='([^~]*)|("[^"]+")' -v OFS="," '{for (i=1;i<=NF;i++) if ($i!~/^\"/) $i="\""$i"\""} 1' file
"eno","ename","address","zip"
"123","abc","","560000"
"245","abc ~ def","hyd","560102"
"333","ghi~jkl","pub","560103"

【讨论】:

  • 最后两行没有按预期工作。
  • @user1485267 你的例子没有显示。我很少看到这种情况发生,但如果你有,你需要一个新的帖子,一个新的问题,一个新的解决方案。
  • @user1485267,我完全同意 Jotne 的观点,请始终发布与您的实际数据接近的正确样本,当您不断更改样本时,我们所有人也很难为您提供帮助。
  • 抱歉更改输入。我同意你的观点。我将在新帖子中添加。感谢您的解决方案 Jotne & Ravindre
  • 您不需要创建新帖子,the one your question was closed as a dup of 向您展示如何解决您的问题,无论您的输入是否包含换行符。只需按照它在那里显示的操作将输入分隔为字段,然后在循环中 gsub(/^"|"$/,"",$i); $i="\""$i"\"" 以在打印记录之前将每个字段用双引号括起来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-08
  • 2018-04-03
  • 2011-03-28
  • 1970-01-01
  • 1970-01-01
  • 2016-08-26
  • 1970-01-01
相关资源
最近更新 更多