如何使用awk将第一行作为文本文件中的标题

时间:2018-09-15 14:40:57

标签: awk sed grep

作为csv文件的输入如下所示

name,id no,marks in cc  
xyzc,10000,56   
ABCb,10001,75   
xyza,10000,56  
xyz1,10000,56  

预期输出如下,即在添加文本文件的第1行虚线之后,也将文本文件从','替换为'^'。

name ^ id no ^ marks in cc  
...........................
xyzc ^ 10000 ^ 56   
ABCb ^ 10001 ^ 75   
xyza ^ 10000 ^ 56  
xyz1 ^ 10000 ^ 56      

我该如何在awk中进行此类安排?有人可以帮助解决此问题

5 个答案:

答案 0 :(得分:4)

这可能对您有用(GNU sed):

sed 's/,/ ^ /g;1p;1s/././g' file

将所有,替换为^。打印第一行,然后将第一行替换为.

答案 1 :(得分:2)

一种替代方法,但基本相同

awk '{gsub(/,/," ^ ")}1;(NR==1){gsub(/./,".")}(NR==1)'  file

此代码实质上执行以下操作:

  1. 读取一行并将其存储在$0中(这是默认设置,没有为此编写的代码)
  2. {gsub(/,/," ^ ")}:将所有, <逗号>替换为字符串" ^ " 并将所有内容存储在{ {1}}
  3. $0:这是等效于1的简写,因此打印字符串{print $0}
  4. $0:如果记录/行号(NR==1){action}等于1,请执行NR,其中action
    1. action :用{gsub(/./,".")} 替换所有字符。这会创建您的下划线
  5. .:这等效于(NR==1),等效于(NR==1)1,后者说明记录/行号是否等于一,打印{{ 1}},现在是一串点。
  6. 返回到 1

注释: 4 5 可能已合并为(NR==1){print $0}

另一个解决方案是:

$0

此代码实质上执行以下操作:

  1. (NR==1){gsub(/./,".");print $0}:将字段分隔符设置为awk '{$1=$1}1;(NR==1){gsub(/./,".")}(NR==1)' FS=, OFS=" ^ " file <逗号>,将输出字段分隔符设置为字符串FS=, OFS=" ^ "
  2. 读取一行并将其存储在,中(这是默认设置,没有为此编写的代码)
  3. " ^ " :通过将所有$0替换为{$1=$1}来重建$0。在第一种情况下,这基本上等于FS
  4. OFS:这是等效于awk '{gsub(/,/," ^ ")}的简写,因此打印字符串1
  5. {print $0}:如果记录/行号$0等于1,请执行(NR==1){action},其中NR
    1. action :用action 替换所有字符。这会创建您的下划线
  6. {gsub(/./,".")}:这等效于.,等效于(NR==1),后者说明记录/行号是否等于一,打印{{ 1}},现在是一串点。
  7. 返回到 2

甚至可以简称为

(NR==1)1

但是这变得更加晦涩难懂,甚至不易理解,甚至引入了很小的错误可能性(请参阅此帖子下方的Ed Morton的评论)

永远不要追求最短的版本,而是最易读和最容易调试的版本。

答案 2 :(得分:2)

啊,另一场比赛。 :-/

到目前为止,我最喜欢potong的sed解决方案。但是,这是一个超小型的awk解决方案:

awk -F, '$1=$1;NR==1&&gsub(/./,".")' OFS=" ^ " file.csv

这是我们正在做的:

  • -F,-将输入字段分隔符设置为,
  • $1=$1-将第一个字段设置为第一个字段。这(1)重写了用FS替换OFS的行,并且(2)应该始终求值为true从而打印该行。这将导致每行都被打印,而输入字段分隔符将替换为输出字段分隔符。
  • NR==1&&gsub(...)-如果我们仍在第一行,则通过用点替换所有其他字符来打印虚线。
  • OFS=" ^ "-设置输出字段分隔符。

此awk解决方案与其他答案不同的方式是,它在用于确定是否打印线条的条件下嵌入了诸如创建虚线之类的功能。

通常,awk脚本被认为由condition { statement }对组成,但是您会注意到,该awk脚本中没有大括号。丢失的{ statement }被认为是{print}。因此,该脚本由两对缺少语句的语句组成-第一条针对每行进行评估,第二条仅针对第一行进行评估,并用于创建虚线。

答案 3 :(得分:1)

{
    gsub(",", " ^ ");
    print;
    if (NR == 1) {
        gsub(/./, ".");
        print;
    }
}

关键思想是NR是awk处理的记录数 至今。您可以测试此变量以管理对 第一行(或任何特定行)。

答案 4 :(得分:1)

$ awk -F',' -v OFS=' ^ ' '{$1=$1; print} NR==1{gsub(/./,"."); print}' file
name ^ id no ^ marks in cc
..........................
xyzc ^ 10000 ^ 56
ABCb ^ 10001 ^ 75
xyza ^ 10000 ^ 56
xyz1 ^ 10000 ^ 56

通常,当您还没有字符串可以转换为某些重复的字符时,要打印特定长度N的字符字符串(或字符串!),请使用str=sprintf("%*s",N,"")并然后将输出中的每个空白char替换为要使用C打印的char(或字符串)gsub(/ /,"C",str)

$ awk -F',' -v OFS=' ^ ' '{$1=$1; print} NR==1{dots=sprintf("%*s",length($0),""); gsub(/ /,".",dots); print dots}' file
name ^ id no ^ marks in cc
..........................
xyzc ^ 10000 ^ 56
ABCb ^ 10001 ^ 75
xyza ^ 10000 ^ 56
xyz1 ^ 10000 ^ 56