如何按照动态格式使用sed和/或awk对文件中每一行的元素进行重新排序

时间:2018-10-05 17:06:04

标签: bash awk

我目前有一个文件,每行包含有序数据。例如:

Peter:Connor:14:40kg
George:Head:56:60kg

我有一个列表函数,将“格式”字符串作为参数。 该字符串包含代表列表中每个可能元素的缩写。在此示例中,缩写为:

%N, %S, %A, %W

这些缩写可以在任何数量的字符之前或之后。

我想打印数据,使其适合接收的字符串格式,将每个缩写替换为列表中相应的元素。例如,我可能会收到:

{%A} [%W] %S %N

%S|%N|%A[[%W]]

我将需要重新排序数据,以使其适合所需的格式。由于它是函数中的一个参数,因此我无法事先知道会收到什么。

{14} [40kg] Connor Peter

第二个例子

Connor|Peter|14[[40kg]]

我如何使用awk做到这一点?

2 个答案:

答案 0 :(得分:0)

awk 'BEGIN{FS=":"; OFS=" "}{print "{"$3"}","["$4"]",$2,$1}' inputFile

给予:

{14} [40kg] Connor Peter
{56} [60kg] Head George

awk 'BEGIN{FS=":"; OFS="|"}{print $2,$1,$3"[["$2"]]"}' inputFile

收益

Connor|Peter|14[[Connor]]
Head|George|56[[Head]]

答案 1 :(得分:0)

假设I might receive...使您能够将具有该值的字符串传递给awk:

$ cat tst.awk
BEGIN {
    FS = ":"
    tmp = fmt
    sub(/^[^[:alpha:]]+/,"",tmp)
    split(tmp,flds,/[^[:alpha:]]+/)
    gsub(/[[:alpha:]]+/,"%s",fmt)
    fmt = fmt ORS
}
NR==1 {
    for (i=1; i<=NF; i++) {
        f[$i] = i
    }
    next
}
{ printf fmt, $(f[flds[1]]), $(f[flds[2]]), $(f[flds[3]]), $(f[flds[4]]) }

$ awk -v fmt='{age} [kilo] surname name' -f tst.awk file
{14} [40kg] Connor Peter
{56} [60kg] Head George

$ awk -v fmt='surname|name|age[[kilo]]' -f tst.awk file
Connor|Peter|14[[40kg]]
Head|George|56[[60kg]]

要使上面的内容起作用,必须有一些命名列的名称。您可以根据需要在脚本中对其进行硬编码,但我将其作为标题行添加到了CSV中:

$ cat file
name:surname:age:kilo
Peter:Connor:14:40kg
George:Head:56:60kg