如何使用awk将第一行作为文本文件的标题
作为csv文件的输入如下所示如何使用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
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
,这现在是一个点串(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
,这现在是一个点串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