linux - 如何在第 3 列本身打印第 3 个字段

标签 linux awk

在我的文件中,我有 3 个字段,我只想打印第三列中的第三个字段,但输出到第一行。请检查我的文件和输出:

猫文件名

1st field     2nd field    3rd field
---------     ---------    -----------
a,b,c,d       d,e,f,g,h    1,2,3,4,5,5

q,w,e,r       t,y,g,t,i    9,8,7,6,5,5

我正在使用以下命令仅在第三列中打印第三个字段

cat filename |awk '{print $3}' |tr ',' '\n' 

OUTPUT 在第一字段位置打印第三字段字符串,我希望仅在第三字段区域打印

first field :-
---------------
1
2
3
4
5 
5

预期输出

1st field     2nd field    3rd field
---------     ---------    -----------
a,b,c,d       d,e,f,g,h     1
                            2
                            3
                            4
                            5 
                            5

q,w,e,r       t,y,g,t,i     9
                            8
                            7
                            6 
                            5
                            5

最佳答案

输入

 [akshay@localhost tmp]$ cat file
 1st field     2nd field    3rd field
 ---------     ---------    -----------
 a,b,c,d       d,e,f,g,h    1,2,3,4,5,5

 q,w,e,r       t,y,g,t,i    9,8,7,6,5,5

脚本

 [akshay@localhost tmp]$ cat test.awk
    NR<3 || !NF{ print; next}
    { 
        split($0,D,/[^[:space:]]*/)
        c1=sprintf("%*s",length($1),"")
        c2=sprintf("%*s",length($2),"")
        split($3,A,/,/)
        for(i=1; i in A; i++)
        {   
            if(i==2)
            {
                $1 = c1
                $2 = c2
            }
            printf("%s%s%s%s%d\n",$1,D[2],$2,D[3],A[i]) 
        }
     }

输出

 [akshay@localhost tmp]$ awk -f test.awk file
 1st field     2nd field    3rd field
 ---------     ---------    -----------
 a,b,c,d       d,e,f,g,h    1
                            2
                            3
                            4
                            5
                            5

 q,w,e,r       t,y,g,t,i    9
                            8
                            7
                            6
                            5
                            5

解释

  • NR<3 || !NF{ print; next}

NR gives you the total number of records being processed or line number, in short NR variable has line number.

NF gives you the total number of fields in a record.

The next statement forces awk to immediately stop processing the current record and go on to the next record.

如果行号小于 3 或不是 NF(表示记录中没有字段是空白行),则打印当前记录并转到下一条记录。

  • split($0,D,/[^[:space:]]*/)

因为我们有兴趣保留格式,所以我们在这里保存数组 D 上的字段之间的分隔符,如果你有 GNU awk,你可以为 split() 使用第四个参数 - 它可以让你拆分该行分为 2 个数组,一个字段和另一个字段之间的分隔符,然后您只需对字段数组进行操作并使用每个字段数组元素之间的分隔符数组进行打印以重建原始 $0

  • c1=sprintf("%*s",length($1),"")c2=sprintf("%*s",length($2),"")

这里sprintf函数用于填充字段($1 or $2)长度的空格字符。

  • split($3,A,/,/)

split(string, array [, fieldsep [, seps ] ])

Divide string into pieces separated by fieldsep and store the pieces in array and the separator strings in the seps array. The first piece is stored in array[1], the second piece in array[2], and so forth. The string value of the third argument, fieldsep, is a regexp describing where to split string (much as FS can be a regexp describing where to split input records). If fieldsep is omitted, the value of FS is used. split() returns the number of elements created.

循环直到i in A为真,才知道i=1i++控制着数组的遍历顺序,感谢Ed Morton

  • if(i==2) { $1 = c1 $2 = c2 }

i = 1 我们打印 a,b,c,dd,e,f,g,h 时,在下一次迭代中,我们用我们在上面创建的 $1$2 修改 c1c2 值,因为您有兴趣按要求只显示一次。

  • printf("%s%s%s%s%d\n",$1,D[2],$2,D[3],A[i])

最后打印出我们上面保存的field1($1),field1和field2之间的分隔符,即D[2],field2($2),field2和field3之间的分隔符以及数组A元素仅由我们创建的一个(split($3,A,/,/))。

关于linux - 如何在第 3 列本身打印第 3 个字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30613893/

相关文章:

bash - 将 bash 变量传递给 awk

shell - 日期:额外的操作数 %d' 错误

linux - BASH shell 脚本在命令提示符下工作正常,但不适用于 crontab

linux - 致命: destination path '/var/cpanel/easy/apache/custom_opt_mods/Cpanel already exists and is not an empty directory

linux - 如何量化 C 内核的 CUDA 设备的处理权衡?

python - 如何使用awk替换所有组合中的不同文本 block ?

bash - 如何删除整个文件中的双行,省略每行中的前 n 个字符?

子进程不读取管道

linux - 如何将命令存储在 shell 脚本的变量中?

linux - 用 awk 解析列