我创建了一个脚本,用于从数据库中提取数据并将其加载到 csv 文件中。我使用的是SunOS hstz1454 5.10系统。有没有办法可以将 csv 文件中的数字翻译/转换为字符串。因此,如果我的第六列是数字1
,请将其转换为字符串Cos4
,或者如果2
第六列有,请将其转换为另一个字符串Cos6
。我之前使用了一个脚本将最后一个字符转换为字符串。可能与我想做的类似。
for fname in conv2015_10_TrafficProfile_data_migration.csv
do
echo "Translate each char to a string $fname"
sed s'/S$/STANDARD/g; s/C$/CUSTOMER/g; $fname > tmp.tmp
mv tmp.tmp $fname
done
我的数据如下所示:
4,2,64,1088,80,1,Y,Y
5,2,64,1088,95,2,Y,Y
6,2,1088,39813120,0,2,Y,Y
7,2,1088,39813120,5,1,Y,Y
8,2,1088,39813120,10,2,Y,Y
答案1
你想要 awk。在我看来,除了简单的替换(并不比 awk 复杂得多sed -e 's/this/that'
)之外,几乎没有任何理由使用 sed 而不是 awk。在这种情况下,尤其会适得其反。
您可以告诉 awk 使用 , 作为分隔符,使用-F,
.我们还可以将逗号放入 awk 的OFS
变量(输出字段分隔符)中,以便print
重新组合位置字段的命令会将它们与逗号组合:
awk -F, 'BEGIN { OFS="," } ...'
现在我们坚持逻辑。 Awk 支持一种“反应式编程”,因为它允许对位置字段变量$1
, $2
, ... 进行赋值。当您对其中任何变量进行赋值时,它会自动重新构造$0
最初保存输入行的变量。它通过组合位置字段及其OFS
之间的位置字段来重建它。因此,我们可以这样做:
awk -F, 'BEGIN { OFS="," }
{ if ($6 == 1) $6 = "Cos4"
else if ($6 == 2) $6 = "Cos6"
print }' yourfile
无需重新编译;如果你六个月后再次访问它,你几乎会立即明白它的作用。
通过将条件测试分解为单独的 awk 规则,可以稍微简化上面的代码。也就是说:
awk -F, 'BEGIN { OFS="," }
$6 == 1 { $6 = "Cos4" }
$6 == 2 { $6 = "Cos6" }
{ print }' yourfile
{ print }
此外,我们可以通过将其替换为以下内容来“编码高尔夫” 1
:
awk -F, 'BEGIN { OFS="," }
$6 == 1 { $6 = "Cos4" }
$6 == 2 { $6 = "Cos6" }
1' yourfile
该常数1
充当布尔真条件。该条件没有操作,因此 Awk 提供了一个默认操作,即{ print }
。然而,现在如果你六个月后再次访问,你将不得不记住这一点;以这种方式缩短计划有时会造成未来的债务。
另一方面,由于我们OFS
在BEGIN
块中设置,所以一个很好的转换是避开该选项,而只是在同一个块中-F
设置:FS
awk 'BEGIN { FS = OFS = "," }
$6 == 1 { $6 = "Cos4" }
$6 == 2 { $6 = "Cos6" }
{ print }' yourfile
我们可以使用复合赋值,就像在 C 语言中一样。如果可能的话,类似的、相关的事情应该以类似的方式紧密地一起完成。
答案2
sed -e's/,/&Cos\n/5' \
-e's/\n1/4/' \
-e's/\n2/6/' \
-e's/Cos\n//' <in >out
但我始终不明白awk
。