AWK 命令参数错误

Mr.*_*ore 2 shell awk shell-script arguments

我有一个数据集,其中包含学生的联系信息,示例数据集如下

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
Run Code Online (Sandbox Code Playgroud)

我正在运行以下命令将地址列内的地址替换为| 将其加载到数据库中。

awk '!(NR%2){gsub(",","|")} {printf RFS $0} {RFS="\""}' RS=\" fileName.txt > output.txt
Run Code Online (Sandbox Code Playgroud)

我面临的问题是每当我运行此命令时它都会返回以下错误,最初它运行正常

awk: run time error: not enough arguments passed to printf(""Jake Lake%, Apartment #22, Main Road, Area XYZ")
Run Code Online (Sandbox Code Playgroud)

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

Ed *_*ton 6

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

这是正确编写问题中的代码的方法:

$ 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
Run Code Online (Sandbox Code Playgroud)

要使用 awk 对 CSV 执行更多操作,请参阅whats-the-most-robust-way-to-efficiently-parse-csv-using-awk