csv文件中的Unix截断列

Mik*_*ike 5 text-processing

如何从 Unix 命令行将列“test10”截断为 5 个字符?

由此

test1,test2,test3,test4,test10,test11,test12,test17
rh,mbn,ccc,khj,ee3 eeeeeEeee ee$eeee e.eeeee2eeeee5eeeeeeee,a2,3,u
hyt,bb,mb,khj,R ee3ee eeEeee ee$eeee e.eeeee2eeeee5eeeeeeee,a,5,r
mbn,htr,ccc,fdf,F1ee eeeeEeee ee$eeee e.eeeee2eeeee5eeeeeeee,a,e,r
Run Code Online (Sandbox Code Playgroud)

对此

test1,test2,test3,test4,test10,test11,test12,test17
rh,mbn,ccc,khj,ee3 e,a2,3,u
hyt,bb,mb,khj,R ee3,a,5,r
mbn,htr,ccc,fdf,F1ee ,a,e,r
Run Code Online (Sandbox Code Playgroud)

ter*_*don 12

如果您的文件确实像您的示例一样简单,则可以执行以下操作之一:

  • awk

    $ awk -F, -vOFS=, 'NR>1{$5=substr($5,1,5)}1' file 
    test1,test2,test3,test4,test10,test11,test12,test17
    rh,mbn,ccc,khj,ee3 e,a2,3,u
    hyt,bb,mb,khj,R ee3,a,5,r
    mbn,htr,ccc,fdf,F1ee ,a,e,r
    
    Run Code Online (Sandbox Code Playgroud)

    解释

    -F,将输入字段分隔符,-vOFS=,将变量OFS(输出字段分隔符)来,NR是当前行号,因此上面的脚本会将第 5 个字段更改为其自身的 5 个字符的子字符串。唯一1的 awk 是“打印此行”的简写。

  • perl

    $ perl -F, -lane '$F[4]=~s/(.{5}).*/$1/ if $.>1; print join ",", @F' file 
    test1,test2,test3,test4,test10,test11,test12,test17
    rh,mbn,ccc,khj,ee3 e,a2,3,u
    hyt,bb,mb,khj,R ee3,a,5,r
    mbn,htr,ccc,fdf,F1ee ,a,e,r
    
    Run Code Online (Sandbox Code Playgroud)

    解释

    -a令Perl像AWK和上由给定的字符分割其输入线-F,并将其保存为数组的元素@F。然后,我们删除第 5 个字段的第 1 个字符以外的所有字符(它们从 开始计数0),然后打印@F以逗号连接的结果数组。

  • sed

    $ sed  -E '1!s/(([^,]+,){4}[^,]{5,5})[^,]*,/\1,/' file
    test1,test2,test3,test4,test10,test11,test12,test17
    rh,mbn,ccc,khj,ee3 e,a2,3,u
    hyt,bb,mb,khj,R ee3,a,5,r
    mbn,htr,ccc,fdf,F1ee ,a,e,r
    
    Run Code Online (Sandbox Code Playgroud)

    解释

    这是一般格式为 的替换运算符s/original.replacement/。的1!意思是“不为1号线做到这一点”。正则表达式匹配一组非,后跟,4 次 ( ([^,]+,){4}),然后是任意 5 个非,字符 ( [^,]{5})——这些是第 5 个字段的第 1 个 5 —— 然后是任何其他直到字段结束( ) 的字符[^,]+,。所有这些都被行的第一部分替换,有效地截断了字段。


Kus*_*nda 5

使用 awk:

$ awk -F "," 'BEGIN { OFS = FS } NR > 1 { $5 = substr($5,1,5) } { print }' data.csv
Run Code Online (Sandbox Code Playgroud)

-F标志设置输入字段分隔符,BEGIN块将输出字段分隔符设置为输入字段分隔符(逗号)。

如果当前记录的序数 ( NR) 大于 1(即我们已传递标题行),则该substr()函数会将第五个字段(列)截断为最多五个字符。这避免了修改输入数据的第一行。

单独print将(可能)修改的记录(行)打印到标准输出。