修改 行数和制表符分隔值也是动态的,因为它可以更改。所以它可能是1-5或1-10,具有相同的布局,但该区域将只列出一次。
我的文件格式如下:(@ TSV)
host1 host2 host3
id1 id2 id3
ip1 ip2 ip3
name1 name2 name3
role1 role2 role3
region
我也可以格式化文件:
host1
host2
host3
id1
id2
id3
ip1
ip2
ip3
name1
name2
name3
role1
role2
role3
region
我想写一个新文件或内联修改此文件,因此文件采用以下格式:(tsv)
host1 id1 ip1 name1 role1 region
host2 id2 ip2 name2 role2 region
host3 id3 ip3 name3 role3 region
我尝试过使用awk,sed,for循环没有成功......我需要一些新的想法。
答案 0 :(得分:0)
您可以使用以下awk
脚本:
# translate.awk
NR==1 {
split($0,hosts)
}
NR==2 {
split($0,ids)
}
NR==3{
split($0,ips)
}
NR==4{
split($0,names)
}
NR==5{
split($0,roles)
}
NR==6{
region=$1
}
END{
OFS="\t"
for(i in hosts) {
print hosts[i], ids[i], ips[i], names[i], roles[i], region
}
}
这样称呼:
awk -f translate.awk input.file
答案 1 :(得分:0)
从列表格式化版本开始,如果您没有丢失数据,即" religion" 3次,这会容易得多。
您可以动态添加缺失的值,然后只需添加pr
$ awk '1; END{print;print}' file | pr -6ts
host1 id1 ip1 name1 role1 region
host2 id2 ip2 name2 role2 region
host3 id3 ip3 name3 role3 region
如果列数已知且只有最后一个值可能丢失,则可以按列数进行参数化
$ cols=6; awk -v cols=$cols '1; END{for(i=1;i<=(NR-cols)/(cols-1);i++) print}' file |
pr -${cols}ts
答案 2 :(得分:0)
将行转换为列的惯用awk方法:
$ cat tst.awk
BEGIN { FS=OFS="\t" }
{
numCols = NR
numRows = (NF>numRows ? NF : numRows)
for (rowNr=1; rowNr<=NF; rowNr++) {
vals[rowNr,numCols] = $rowNr
}
}
END {
for (rowNr=1; rowNr<=numRows; rowNr++) {
for (colNr=1; colNr<=numCols; colNr++) {
val = ((rowNr,colNr) in vals ? vals[rowNr,colNr] : vals[1,colNr])
printf "%s%s", val, (colNr<numCols ? OFS : ORS)
}
}
}
$ awk -f tst.awk file
host1 id1 ip1 name1 role1 region
host2 id2 ip2 name2 role2 region
host3 id3 ip3 name3 role3 region
以上是在您的第一个输入文件上运行的:
$ cat file
host1 host2 host3
id1 id2 id3
ip1 ip2 ip3
name1 name2 name3
role1 role2 role3
region
请注意,脚本不会引用输入中的任何值,也不会引用您有多少行或列,也不会引用任何其他有关输入文件内容的假设,除非缺少值,您希望重复第一个。