我正在通过亚马逊的 ec2 命令行工具请求 ec2 快照列表:
ec2-describe-snapshots -H --hide-tags > snapshots.csv
数据看起来像这样:
SnapshotId VolumeId StartTime OwnerId VolumeSize Description
snap-00b66464 vol-b99a38d0 2012-01-05 5098939 160 my backup
如何在将数据重定向到之前拦截数据snapshots.csv
并执行以下操作:
- 将“制表符”替换为逗号
- 用引号封装值
- 如果值全是数字,请在其前面加上前缀,
=
以便 excel 将其视为文本 - 例如OwnerId
应该是"=5098939
“(如果无法内联完成,则不需要此前缀,而是需要脚本文件或函数)
期望的输出:
"SnapshotId","VolumeId","StartTime","OwnerId","VolumeSize","Description"
"snap-00b66464","vol-b99a38d0","2012-01-05","=5098939","=160","my backup"
答案1
#!/usr/bin/awk -f
BEGIN { FS = "\t"; OFS = "," }
{
for(i = 1; i <= NF; i++) {
if ($i + 0 == $i) { $i = "=" $i }
else gsub(/"/, "\"\"", $i);
$i = "\"" $i "\""
}
print
}
假设您指定了此名称convert.awk
,您可以使用以下任一方式进行调用
ec2-describe-snapshots -H --hide-tags | awk -f convert.awk > snapshots.csv
或(添加执行权限后,chmod a+x convert.awk
)
ec2-describe-snapshots -H --hide-tags | ./convert.awk > snapshots.csv
这将为每个选项卡创建一个新列,这会将注释列放在一起(除非它包含选项卡),但添加空列(尽管这就是示例输出的外观,所以也许您确实想要这样做)。如果您想拆分所有空白(这将折叠表中的额外选项卡,但将描述中的每个单词作为新列),请取出该FS="\t";
语句。
对于后代,如果不需要"
s 或=
s 或嵌入空格,可以将其设为单行:
awk -v OFS=, '{$1=$1;print}'
答案2
这是一个 Perl 解决方案。这对于 sed/awk 来说可能是可能的,但是对数字部分的测试可能会使其变得非常难看。
ec2-describe-snapshots -H --hide-tags | \
perl -e 'use Scalar::Util qw(looks_like_number);
while (chomp($line = <STDIN>)) {
print(join(",", map { "\"" . (looks_like_number($_) ? "=$_" :
do {s/"/""/g; $_}) . "\"" }
split(/\t/, $line)) . "\n");
}' \
> snapshots.csv
答案3
如果您像我一样懒,并且想在一个命令行上完成所有操作而不编写脚本,那么我会这样做。
ec2-describe-snapshots -H --hide-tags | sed -e 's/^I/","/g' | sed -e 's/^/"/' | sed -e 's/$/"/'> snapshots.csv
这^I
是通过按ctrl+来完成的v i。
第一个sed
将所有的交换tabs
为","
。第二个在每行的开头sed
插入 a ,最后一个 sed在每行的末尾插入一个结束符。"
"
答案4
sed 是我遇到过的最有用的 Linux 实用程序。
sed 's/\t/","/g' TabSeparatedValues.txt > CommaSeparatedValues.csv
sed -i 's/.*/"&"/' CommaSeparatedValues.csv
第一个命令用逗号和引号替换每行中的所有制表符。第二个命令在每行的开头和结尾插入引号,以便每个值都用引号引起来,这允许逗号成为值的一部分。