首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >AWK命令参数错误

AWK命令参数错误
EN

Unix & Linux用户
提问于 2021-10-21 08:33:59
回答 2查看 371关注 0票数 2

我有一个包含学生联系信息的数据集,样本数据集如下

代码语言:javascript
复制
First Name, Last Name, Address, Phone Number
John, Doe, "House # 11, Street xyz, Road, Area",00000000
Sara, Taylor, "Jake Lake%, Apartment #22, Main Road, Area XYZ", 00000000

我正在运行下面的命令来替换内部地址列,以将其加载到DB中。

代码语言:javascript
复制
awk '!(NR%2){gsub(",","|")} {printf RFS $0} {RFS="\""}' RS=\" fileName.txt > output.txt

我面临的问题是,每当我运行此命令时,它将返回以下错误,最初运行的是ok。

代码语言:javascript
复制
awk: run time error: not enough arguments passed to printf(""Jake Lake%, Apartment #22, Main Road, Area XYZ")

有什么解决办法吗?我注意到%即将出现在地址中,这是问题所在吗?

EN

回答 2

Unix & Linux用户

回答已采纳

发布于 2021-10-21 13:11:34

  1. 为了健壮性,永远不要使用printf $0,始终使用printf "%s", $0,因为当输入包含printf格式字符时,前者将失败(正如您当前看到的那样)。这同样适用于对任何输入数据使用printf
  2. 为了清晰和健壮性,永远不要使用大写变量名,例如RFS,以避免与内置变量名称发生冲突,并避免混淆代码,使代码看起来像是在使用内置变量。
  3. 为了提高可读性,不要在脚本之后设置变量(例如RS ),除非您需要将它们设置为不同输入文件的不同值,在脚本开始之前或开始时设置变量,因此在读取脚本时,我们会在看到它们被使用之前看到它们正在设置。
  4. 为了高效、简单、健壮,*sub()的第一个参数是regexp,而不是字符串,所以使用regexp (/.../),而不是string ("...")分隔符,除非出于某种原因需要动态而不是静态的regexp。
  5. 为了清晰性和可维护性,当您有两个必须具有相同值的变量(例如RSRFS )时,不要分别将它们设置为相同的值,例如RS="\""; RFS="\"",或者将它们一起设置为该值,例如RS=RFS="\"",或者将其中一个设置为另一个,例如RS="\""; RFS=RS

以下是如何正确地编写问题中的代码:

代码语言:javascript
复制
$ awk -v RS='"' '!(NR%2){gsub(/,/,"|")} {printf "%s%s", rfs, $0; rfs=RS}' file
First Name, Last Name, Address, Phone Number
John, Doe, "House # 11| Street xyz| Road| Area",00000000
Sara, Taylor, "Jake Lake%| Apartment #22| Main Road| Area XYZ", 00000000

若要使用使用awk的CSV做更多的工作,请参见undefined

票数 6
EN

Unix & Linux用户

发布于 2021-10-21 09:54:05

您所得到的错误是由于将RFS (一个空变量)和$0的值作为格式字符串与printf连接所致。

您的文件是一个有效的CSV文件,除了在一些分隔逗号之后有空格(这会扰乱Address字段的引用;引用的字段需要在分隔符后面直接具有初始引号)。我们可以使用csvformat (来自https://csvkit.readthedocs.io/en/latest/的csvkit的一部分)来纠正这个问题:

代码语言:javascript
复制
$ csvformat --skipinitialspace file.csv >fixed-file.csv
$ cat fixed-file.csv
First Name,Last Name,Address,Phone Number
John,Doe,"House # 11, Street xyz, Road, Area",00000000
Sara,Taylor,"Jake Lake%, Apartment #22, Main Road, Area XYZ",00000000

能够解析CSV的数据库应该能够按原样读取它。

您是否仍然希望将所有嵌入的逗号替换到|中,只需将文件的分隔符更改为逗号以外的分隔符(我将在下面使用制表符),将其余的逗号更改为管道,并再次更改为使用逗号分隔符。

我们可以直接在原始数据上这样做:

代码语言:javascript
复制
$ csvformat --skipinitialspace --out-tabs file.csv | tr ',' '|' | csvformat --tabs >fixed-file.csv
$ cat fixed-file.csv
First Name,Last Name,Address,Phone Number
John,Doe,House # 11| Street xyz| Road| Area,00000000
Sara,Taylor,Jake Lake%| Apartment #22| Main Road| Area XYZ,00000000

使用的各种long选项的短变体是-S for --skipinitialspace-T for --out-tabs-t for --tabs

票数 2
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/674185

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档