(sed/awk)如何将字段分隔(如csv)文件转换为具有固定大小制表符分隔列的txt文件?

(sed/awk)如何将字段分隔(如csv)文件转换为具有固定大小制表符分隔列的txt文件?,csv,sed,awk,format,Csv,Sed,Awk,Format,我有一个类似csv的文件,其中字段分隔符是“@” ID@Name@Surname@Age@Profession@Address 1254343123@John@Smith@24@Engineer@Washington 23@Alexander@Kristofferson-Brown@Economic Advisor@Kent ... …这并不是在所有情况下都有效 有人能给我一个如何进行的提示吗 PS:我的意图是主要使用sed(一行代码),或者如果sed不剪切它,awk也可以 awk -F@ '{

我有一个类似csv的文件,其中字段分隔符是“@”

ID@Name@Surname@Age@Profession@Address

1254343123@John@Smith@24@Engineer@Washington 23@Alexander@Kristofferson-Brown@Economic Advisor@Kent ... …这并不是在所有情况下都有效

有人能给我一个如何进行的提示吗

PS:我的意图是主要使用sed(一行代码),或者如果sed不剪切它,awk也可以

awk -F@ '{for(i=1;i<=NF;i++){printf "%-20s", $i};printf "\n"}' input.csv
输出
awk-F'{for(i=1;i
awk-F'{print$1”\t“$2”\t“$3”\t“$4”\t“$5”\t“$6}”file.csv>readable.txt


使用awk列和打印列的分隔符选项,将
\t
放在每个列之间,尝试使用此选项。

BSD、Mac OS X和Linux有
命令:

column -t -s@
但它会生成空格,而不是制表符(而且应该是这样,因为制表符已过时)。输出:


我的转换excel默认csv(逗号分隔,用双引号括起来的文本)的解决方案是以下awk脚本:

#!/bin/nawk -f
# Q&D to transform csv (with commas imbedded in quotes) to pipe (|)
# Usage: cma2pipe.awk <in.csv> > <out.csv>
# Note: Assumes that <in.csv> contains no ~ or |  
{#MAIN
  s=$0;c=0;f=0;        #reset varibles for a line
  while (c<length(s)){ #loop thru line
    c++;               #char counter
    a=substr(s,c,1);   #get current character
    if (a=="\"")f++;   #flag quote
    if (f%2==1&&a==",")#if inside pair of quotes, look for ","
      s= repl("~",c,s);#replace commas with ~
  }#end while c
  gsub(",","|",s);     #replace remaining , with |
  gsub("~",",",s);     #put commas back
  gsub("\"","",s);     #get rid of quotes
print s
}#end MAIN
function repl(r,n,t){  #replace single character in string
  s1=substr(t,1,n-1);  #get first part of string
  s2=substr(t,n+1);    #get last part of string
  return(s1 r s2);     #return changed string
}#end repl()
!/bin/nawk-f
#Q&D将csv(引号中嵌入逗号)转换为管道(|)
#用法:cma2pipe.awk>
#注:假设不包含~或|
{#MAIN
s=$0;c=0;f=0;#为一行重置变量

while(cw)您描述的不是CSV文件。无论如何,您不能将所有出现的“@”替换为“”?否。如果我添加空格,则没有一致的列宽。因此它不是“人类可读的”。我想要一个类似表格的格式输出。
awk'$0=gensub(@),“\t”,“g”)'file.csv
是一种更好的方法,因为它不依赖于字段的数量(也不依赖于较短的脚本)。但无论添加多少选项卡,列都不会对齐,因为您需要约束字段宽度,而不仅仅是间距。
awk-F'{$1=$1;print}'OFS='\t'file.csv
(或
awk-F'{$1=$1}1'OFS='\t'file.csv
)@manuel:要设置每列的宽度:
开始{widthlist=“20 10 30 12…”;拆分(widthlist,widths,”)}{…printf“%-*s”,宽度[i],$i…
我认为拉斯曼的回答中的列命令是一种更好的方法。@pbh101如果你看看我一年前对他的回答所做的评论,你会发现我也这么认为:)遗憾的是,Windows命令shell中没有可供使用的列实用程序-只有在不理解语法和语义之间的差异的情况下,在GnuWin32Tabs上找不到任何内容才是过时的。您可以始终通过实用程序“expand”来使用列实用程序为了实现从空格到tabsThanks的转换,我对其进行了调整,将空格分隔、双引号封装的TXT文件转换为标准CSV:
$ cat input.csv
1254343123@John@Smith@24@Engineer@Washington
23@Alexander@Kristofferson-Brown@35@Economic Advisor@Kent
$ awk -F@ '{for(i=1;i<=NF;i++){printf "%-20s", $i};printf "\n"}' input.csv
1254343123          John                Smith               24                  Engineer            Washington
23                  Alexander           Kristofferson-Brown 35                  Economic Advisor    Kent
#!/bin/bash

fldwth=20

awk -v fw=$fldwth -F@ '{for(i=1;i<=NF;i++){printf "%-*s", fw,$i};printf "\n"}' input.csv
column -t -s@
1254343123  John       Smith                24  Engineer          Washington
23          Alexander  Kristofferson-Brown  35  Economic Advisor  Kent
#!/bin/nawk -f
# Q&D to transform csv (with commas imbedded in quotes) to pipe (|)
# Usage: cma2pipe.awk <in.csv> > <out.csv>
# Note: Assumes that <in.csv> contains no ~ or |  
{#MAIN
  s=$0;c=0;f=0;        #reset varibles for a line
  while (c<length(s)){ #loop thru line
    c++;               #char counter
    a=substr(s,c,1);   #get current character
    if (a=="\"")f++;   #flag quote
    if (f%2==1&&a==",")#if inside pair of quotes, look for ","
      s= repl("~",c,s);#replace commas with ~
  }#end while c
  gsub(",","|",s);     #replace remaining , with |
  gsub("~",",",s);     #put commas back
  gsub("\"","",s);     #get rid of quotes
print s
}#end MAIN
function repl(r,n,t){  #replace single character in string
  s1=substr(t,1,n-1);  #get first part of string
  s2=substr(t,n+1);    #get last part of string
  return(s1 r s2);     #return changed string
}#end repl()