(sed/awk)如何将字段分隔(如csv)文件转换为具有固定大小制表符分隔列的txt文件?
我有一个类似csv的文件,其中字段分隔符是“@” ID@Name@Surname@Age@Profession@Address 1254343123@John@Smith@24@Engineer@Washington 23@Alexander@Kristofferson-Brown@Economic Advisor@Kent ... …这并不是在所有情况下都有效 有人能给我一个如何进行的提示吗 PS:我的意图是主要使用sed(一行代码),或者如果sed不剪切它,awk也可以(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@ '{
awk -F@ '{for(i=1;i<=NF;i++){printf "%-20s", $i};printf "\n"}' input.csv
输出
awk-F'{for(i=1;iawk-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()