Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用awk将第一行作为文本文件的标题_Awk_Sed_Grep - Fatal编程技术网

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

如何使用awk将第一行作为文本文件的标题,awk,sed,grep,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 xyz

作为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做这样的安排?有人能帮我解决这个问题吗

{
    gsub(",", " ^ ");
    print;
    if (NR == 1) {
        gsub(/./, ".");
        print;
    }
}
关键思想是
NR
是awk处理的记录数 目前为止您可以测试此变量以管理
第一行(或任何特定行)。

一个轻微的替代,但基本相同

awk '{gsub(/,/," ^ ")}1;(NR==1){gsub(/./,".")}(NR==1)'  file
此代码基本上执行以下操作:

  • 读取一行并将其存储在
    $0
    中(这是默认设置,没有为此编写代码)
  • {gsub(/,/,“^”)}
    用字符串
    “^”
    替换所有
    ,并将所有内容存储在
    $0
  • 1
    这是一种速记,相当于
    {print$0}
    ,所以打印字符串
    $0
  • (NR==1){action}
    如果记录/行号
    NR
    等于1,则执行
    操作
    ,其中
    操作
  • {gsub(/./,“)}
    替换所有字符。这将创建下划线
  • (NR==1)
    这相当于
    (NR==1)1
    ,它相当于
    (NR==1){print$0}
    ,它说明如果记录/行号等于一,则再次打印
    $0
    ,这现在是一个点串
  • 返回到1
  • 注意:45可以合并为
    (NR==1){gsub(/。/,“);print$0}

    另一个解决办法是:

    awk '{$1=$1}1;(NR==1){gsub(/./,".")}(NR==1)'  FS=, OFS=" ^ " file
    
    此代码基本上执行以下操作:

  • FS=,OFS=“^”
    将字段分隔符设置为
    ,将输出字段分隔符设置为字符串
    “^”
  • 读取一行并将其存储在
    $0
    中(这是默认设置,没有为此编写代码)
  • {$1=$1}
    通过将所有
    FS
    替换为
    OFS
    来重建
    $0
    。在第一种情况下,这本质上相当于
    awk'{gsub(/,/,“^”)}
  • 1
    这是一种速记,相当于
    {print$0}
    ,所以打印字符串
    $0
  • (NR==1){action}
    如果记录/行号
    NR
    等于1,则执行
    操作
    ,其中
    操作
  • {gsub(/./,“)}
    替换所有字符。这将创建下划线
  • (NR==1)
    这相当于
    (NR==1)1
    ,它相当于
    (NR==1){print$0}
    ,它说明如果记录/行号等于一,则再次打印
    $0
    ,这现在是一个点串
  • 返回到2
  • 这甚至可以缩短为

    awk '($1=$1);(NR==1) && gsub(/./,".")'  FS=, OFS=" ^ " file
    
    但这变得更加神秘,不可读,甚至引入了一个小错误的可能性(见下面的Ed Morton评论)

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

    $ 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,””)
    然后使用
    gsub(//,“C”)将输出中的每个空白字符替换为要打印的字符(或字符串)
    C
    ,str)

    这可能适用于您(GNU-sed):


    ^
    替换所有
    。打印第一行,然后用
    替换第一行。

    啊,另一场比赛:-/

    到目前为止,我最喜欢Poton的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}
    。因此,脚本由两对缺少语句的语句组成——第一对语句对每一行求值,第二对语句只对第一行求值,并用于创建虚线。

    是否仅用
    ^
    代替
    ?请确认一下。你能告诉我们你目前的尝试吗?在没有看到代码的情况下很难帮助调试代码。很好,您已经包含了示例输入和预期输出,但是尝试创建一个。您可以详细说明第一个吗..只是为了让我了解一些知识:)当您在没有特定需要的情况下使用操作作为条件时,您会混淆您的代码,并且经常引入依赖输入的错误(就像您在本例中所做的那样-尝试
    echo'0'| awk'$1=$1'
    )。所以不要这样做-除非您有特殊的需要,否则,请始终在
    sed 's/,/ ^ /g;1p;1s/././g' file
    
    awk -F, '$1=$1;NR==1&&gsub(/./,".")' OFS=" ^ " file.csv