html tool

2021年12月14日星期二

转:awk转置文本内容

 参考:https://www.leaflag.cn/2019/03/17/%E8%BD%AC%E7%BD%AE%E6%96%87%E4%BB%B6/#%E5%89%8D%E7%BD%AE%E7%9F%A5%E8%AF%86


前置知识

awk是啥?awk是一种优良的文本处理工具,它不仅是Linux中也是任何环境中现有的功能最强大的数据处理引擎之一。先来了解一下解决这个问题需要用到的awk里的指令:

  1. NF:这个表示的是字段总数;
  2. NR:这个表示的是所读文件的当前行数;
  3. $0:表示当前行的所有内容,比如print $0可以打印整行内容;
  4. $i:表示第i个字段;
  5. BEGIN,END:这两个个标识程序开始和结束。

开始写!

awk的shell格式是awk ‘{XXXX}’ filename,
所以我们可以使用这样的命令:

复制成功
awk '{
for(i=1;i<=NF;i++){
if(NR==1){
file[i]=$i #这里如果打印file[i],会发现是两行,第一行是name,第二行是age。和其它语言的数组打印格式不同
}else{
file[i]=file[i] " " $i #因为输出要求有空格
}
}
}
END{
for(i=1;i<=NF;i++){
print file[i]
}
}' file.txt

这里为了好看一些,排了个版,当然我们需要在终端直接输入一整行指令,存成文件也可以,不过估计得改一下文件路径:

awk '{for(i=1;i<=NF;i++){if(NR==1){file[i]=$i}else{file[i]=file[i]" "$i}}}END{for(i=1;i<=NF;i++) print file[i]}' file.txt

为什么这样写?

现在来解释一下。我们知道file.txt有三行,每行两个字段,所以NF=2;
如果文件只有一行,即NR=1的话,直接构造一个数组把字段存进去即可得到转置后的文件(注释里有,自己也可以试着打印一下)。得到NR=1是的file数组输出:

name
age

接着开始读取下一行,又重新开始循环,i=1,此时NR=2,所以执行else里面的代码,此时会在原有file数组里增加file.txt第二行的字段(file[i]=file[i] “ “ $i),第一次循环:

name alice
age 21

至此,第二次循环后执行END结束里的指令,得到我们想要的输出。
值得注意的是每次读完一行,都会这一行的开始读取字段,重新循环是一个点

没有评论:

发表评论