我这里有一个正在使用的脚本。我现在想扩展这一点。
POSIXLY_CORRECT=1 awk -F ';' -v OFS=';' '
{print $0, NR == 1 ? "Price" : $1 ? $1 : $3 * 1.2}' < file.csv
如果第 1 列中没有零,则用 1.2 计算字段 3 但我想,如果字段 1 为零或什么都没有,则用 1.2 计算字段 3 这可能吗?
这是我的电子表格或 CSV 文件:
Sales Price;External ID;Cost;Internal reference;Name;Sales Description
73;1000-04;141,35;1000-04;Jabra GN 1000 RHL Remote Handset Lifter;Manueller Lifter bzw. Hook-Switch
0;0440-729;61,72;0440-729;Jabra GN 1000 RHL, zbh. für Siemens Optiset; Siemens Optiset Telefone
215;2126-82-04;221,8;2126-82-04;Jabra 2100 Mono QD 3-in-1 Set;Typ: 82 E-STD, Noise-Cancelling Mikrofonarm: Flexibel
0;01.01.8800;11,3;01.01.8800;Jabra Kabel QD -> RJ10 Standard spiral;RJ10
结果应该是这样的
Sales Price;External ID;Cost;Internal reference;Name;Sales Description;Price
73;1000-04;141,35;1000-04;Jabra GN 1000 RHL Remote Handset Lifter;Manueller Lifter bzw. Hook-Switch;73
0;0440-729;61,72;0440-729;Jabra GN 1000 RHL, zbh. für Siemens Optiset; Siemens Optiset Telefone;74,064
215;2126-82-04;221,8;2126-82-04;Jabra 2100 Mono QD 3-in-1 Set;Typ: 82 E-STD, Noise-Cancelling Mikrofonarm: Flexibel;215
0;01.01.8800;11,3;01.01.8800;Jabra Kabel QD -> RJ10 Standard spiral;RJ10;13,56
我现在创建了包含以下内容的 calc.sh:
#!/bin/sh
POSIXLY_CORRECT=1 awk '
BEGIN { FS=OFS=";" }
{
if (NR == 1) val = "Price"
else val = ($9 ? $5 * 1.2 : $9)
print $0, val
}
' /test.csv
我像这样运行该文件:
calc.sh > /opt/price/result.csv
这是结果:
Sales Price;External ID;Cost;Internal reference;Name;Sales Description
;Price
73;1000-04;141,35;1000-04;Jabra GN 1000 RHL Remote Handset Lifter;Manueller Lifter bzw. Hook-Switch
;
0;0440-729;61,72;0440-729;Jabra GN 1000 RHL, zbh. für Siemens Optiset; Siemens Optiset Telefone
;
215;2126-82-04;221,8;2126-82-04;Jabra 2100 Mono QD 3-in-1 Set;Typ: 82 E-STD, Noise-Cancelling Mikrofonarm: Flexibel
;
0;01.01.8800;11,3;01.01.8800;Jabra Kabel QD -> RJ10 Standard spiral;RJ10;
价格在第二行。为什么?
我还可以在某处指定价格应在第 xx 列中输出吗?
答案1
要改变你现有的逻辑:
如果第 1 列没有零,则用 1.2 计算第 3 列
您想要什么:
如果字段 1 为零或无,则用 1.2 计算字段 3
只需改变你所拥有的:
$1 ? $1 : $3 * 1.2
否定条件:
!$1 ? $1 : $3 * 1.2
或交换值的顺序:
$1 ? $3 * 1.2 : $1
交换值的顺序会更好,因为它避免了条件 ,$1 ?
部分中的负数和“else”, , 部分中的双重负数: $1
。
看https://en.wikipedia.org/wiki/Ternary_conditional_operator了解如何读取/使用三元表达式。
话虽如此 - 不要嵌套三元表达式,因为这会使您的代码难以阅读,并且始终在三元表达式周围放置括号,以使它们更易于阅读并避免在某些 awks 的某些上下文中出现语法错误(例如,参见https://unix.stackexchange.com/a/588743/133219)。
所以而不是:
{print $0, NR == 1 ? "Price" : $1 ? $3 * 1.2 : $1}
你应该写:
{
if (NR == 1) val = "Price"
else val = ($1 ? $3 * 1.2 : $1)
print $0, val
}
或类似的。
另外,代替:
awk -F ';' -v OFS=';' 'script'
考虑使用:
awk 'BEGIN{FS=OFS=";"} script'
因此,当您需要 FS 和 OFS 具有相同的值时,您不必在 2 个位置硬编码相同的分隔符 ( ;
) - 这使您的代码稍微清晰一些,并且意味着您只需更改 1 个位置(如果/当您决定这样做时)更改分隔符。
我发现您无法理解上述内容,因此为了清楚起见,我建议您的完整脚本应该是:
POSIXLY_CORRECT=1 awk '
BEGIN { FS=OFS=";" }
{
if (NR == 1) val = "Price"
else val = ($1 ? $3 * 1.2 : $1)
print $0, val
}
' file.csv
看https://www.gnu.org/software/gawk/manual/gawk.html#Locale-influences-conversions为什么您需要POSIXLY_CORRECT=1
在小数点分隔符,
而不是 的区域设置中.
。