awk 在输出中打印不必要的新行
awk prints unnecessary new line in output
我正在尝试从以下数据(Elasticsearch 数据)创建 csv 文件
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open 78_data_store-2021.12.12 cYZDB7NGQbyowP-WyF99Zw 1 1 5438232 0 8.3gb 4.1gb
green open 78_data_store-2021.12.24 RWrhN4QKT2OlbP4MB7CYmw 1 1 663431 0 745.3mb 372.6mb
green open 78_data_store-2021.11.26 CivwBCtAROCejmpZ6RaXOA 1 1 989983 0 956.5mb 478.2mb
我想要低于输出(预期输出)
78,78_data_store-2021.11.26,2021.11.26,1,1,478.2mb
78,78_data_store-2021.12.12,2021.12.12,1,1,4.1gb
78,78_data_store-2021.12.24,2021.12.24,1,1,372.6mb
但是当我使用下面的命令时,我在输出中得到了不必要的新行
cat filename | grep " 78_" | sort -k 3 | awk '{split(,a,"_");print a[1];split(,a,"-"); print "," "," a[2] "," "," "," }'
此命令的输出
78
,78_data_store-2021.11.26,2021.11.26,1,1,478.2mb
78
,78_data_store-2021.12.12,2021.12.12,1,1,4.1gb
78
,78_data_store-2021.12.24,2021.12.24,1,1,372.6mb
命令中缺少什么?
print
默认添加换行符。您可以改用 printf("%s", a[1]);
或将 a[1]
的打印移至打印所有其他字段的位置。我已将 a
的第一次使用重命名为 b
而不是能够将值保留到以后:
grep " 78_" filename | sort -k 3 | \
awk '{split(,b,"_");split(,a,"-"); print b[1] "," "," a[2] "," "," "," }'
输出:
78,78_data_store-2021.11.26,2021.11.26,1,1,478.2mb
78,78_data_store-2021.12.12,2021.12.12,1,1,4.1gb
78,78_data_store-2021.12.24,2021.12.24,1,1,372.6mb
根据您显示的示例,请尝试以下 awk
代码。在 awk
中使用 Schwartzian transform
。这里也使用 awk
+ sort
+ awk
组合。
awk '
BEGIN{ OFS="," }
FNR>1 && /78_/{
split(,arr,"[_-]")
print arr[4]"@"arr[1],,arr[4],,,$NF
}
' Input_file |
sort -t'@' -k1 |
awk '{sub(/^[^@]*@/,"")} 1'
上面代码的解释:
- 正在将 Input_file(OP 的文件)传递到
awk
程序中。
- 在此处将所有行的
OFS
设置为逗号。
- 检查条件,如果它大于第一行并且其中有 78_ 则只能进一步移动。
- 使用
split
函数将第 3 个字段拆分为名为 arr 的数组,此处的分隔符为 _-
。
- 打印
arr[4]"@"arr[1],,arr[4],,,$NF
这是根据需要的输出,唯一的事情是在输出的前面添加 arr[4]@
以便我们可以轻松地对其进行排序(可以在本程序的后面删除)。
- 将
awk
程序的输出传递给 sort
命令,其中将字段分隔符设置为 @
并使用第一个字段对其进行排序(例如:示例中的 2021.12.12)。
- 将排序后的数据传递给另一个
awk
程序,其中删除从值开始到第一次出现 @
的所有内容(如上一步所述额外添加)。
OP 尝试的改进:
- 我们在使用
awk
时不需要使用grep
,它可以自己搜索字符串,因此将其从答案中删除。
- 我们不需要使用 2 次
split
,也可以通过在 split
中提及多个分隔符将其合并为一个 split
。
我正在尝试从以下数据(Elasticsearch 数据)创建 csv 文件
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size
green open 78_data_store-2021.12.12 cYZDB7NGQbyowP-WyF99Zw 1 1 5438232 0 8.3gb 4.1gb
green open 78_data_store-2021.12.24 RWrhN4QKT2OlbP4MB7CYmw 1 1 663431 0 745.3mb 372.6mb
green open 78_data_store-2021.11.26 CivwBCtAROCejmpZ6RaXOA 1 1 989983 0 956.5mb 478.2mb
我想要低于输出(预期输出)
78,78_data_store-2021.11.26,2021.11.26,1,1,478.2mb
78,78_data_store-2021.12.12,2021.12.12,1,1,4.1gb
78,78_data_store-2021.12.24,2021.12.24,1,1,372.6mb
但是当我使用下面的命令时,我在输出中得到了不必要的新行
cat filename | grep " 78_" | sort -k 3 | awk '{split(,a,"_");print a[1];split(,a,"-"); print "," "," a[2] "," "," "," }'
此命令的输出
78
,78_data_store-2021.11.26,2021.11.26,1,1,478.2mb
78
,78_data_store-2021.12.12,2021.12.12,1,1,4.1gb
78
,78_data_store-2021.12.24,2021.12.24,1,1,372.6mb
命令中缺少什么?
print
默认添加换行符。您可以改用 printf("%s", a[1]);
或将 a[1]
的打印移至打印所有其他字段的位置。我已将 a
的第一次使用重命名为 b
而不是能够将值保留到以后:
grep " 78_" filename | sort -k 3 | \
awk '{split(,b,"_");split(,a,"-"); print b[1] "," "," a[2] "," "," "," }'
输出:
78,78_data_store-2021.11.26,2021.11.26,1,1,478.2mb
78,78_data_store-2021.12.12,2021.12.12,1,1,4.1gb
78,78_data_store-2021.12.24,2021.12.24,1,1,372.6mb
根据您显示的示例,请尝试以下 awk
代码。在 awk
中使用 Schwartzian transform
。这里也使用 awk
+ sort
+ awk
组合。
awk '
BEGIN{ OFS="," }
FNR>1 && /78_/{
split(,arr,"[_-]")
print arr[4]"@"arr[1],,arr[4],,,$NF
}
' Input_file |
sort -t'@' -k1 |
awk '{sub(/^[^@]*@/,"")} 1'
上面代码的解释:
- 正在将 Input_file(OP 的文件)传递到
awk
程序中。 - 在此处将所有行的
OFS
设置为逗号。 - 检查条件,如果它大于第一行并且其中有 78_ 则只能进一步移动。
- 使用
split
函数将第 3 个字段拆分为名为 arr 的数组,此处的分隔符为_-
。 - 打印
arr[4]"@"arr[1],,arr[4],,,$NF
这是根据需要的输出,唯一的事情是在输出的前面添加arr[4]@
以便我们可以轻松地对其进行排序(可以在本程序的后面删除)。 - 将
awk
程序的输出传递给sort
命令,其中将字段分隔符设置为@
并使用第一个字段对其进行排序(例如:示例中的 2021.12.12)。 - 将排序后的数据传递给另一个
awk
程序,其中删除从值开始到第一次出现@
的所有内容(如上一步所述额外添加)。
OP 尝试的改进:
- 我们在使用
awk
时不需要使用grep
,它可以自己搜索字符串,因此将其从答案中删除。 - 我们不需要使用 2 次
split
,也可以通过在split
中提及多个分隔符将其合并为一个split
。