如何在BASH中使用AWK和fprint解析文本文件?

时间:2016-03-28 22:29:13

标签: linux awk printf

我有一个sample.txt文件,如下所示:

Name         City    ST Zip CTY
John Smith   BrooklynNY10050USA
Paul DavidsonQueens  NY10040USA
Michael SmithNY      NY10030USA
George HermanBronx   NY10020USA

输入图像(如果上传没有正确显示) Input

所需的输出分为不同的列,如下所示:

Desired Output

我试过了:

#!/bin/bash
awk '{printf "%13-s %-8s %-2s %-5s %-3s\n", $1, $2, $3, $4, $5}' sample.txt > new.txt

这个结果不成功:

Name          City     ST Zip   CTY

John          Smith    BrooklynNY10050USA

Paul          DavidsonQueens NY10040USA

Michael       SmithNY  NY10030USA

George        HermanBronx NY10020USA

如果有人可以调整这个,那么文本文件将采用分隔格式,如上所示。非常感谢你!!

3 个答案:

答案 0 :(得分:1)

使用gawk,您可以在BEGIN块中设置输入字段宽度:

$ gawk 'BEGIN { FIELDWIDTHS = "13 8 2 5 3" } { print $1, $2, $3, $4, $5 }' fw.txt
Name          City     ST  Zip  CTY
John Smith    Brooklyn NY 10050 USA
Paul Davidson Queens   NY 10040 USA
Michael Smith NY       NY 10030 USA
George Herman Bronx    NY 10020 USA

如果你的awk没有FIELDWIDTHS,那有点单调乏味但你可以使用substr

$ awk '{ print substr($0,1,13), substr($0,14,8), substr($0,22,2), substr($0,24,5), substr($0,29,3) }' fw.txt
Name          City     ST  Zip  CTY
John Smith    Brooklyn NY 10050 USA
Paul Davidson Queens   NY 10040 USA
Michael Smith NY       NY 10030 USA
George Herman Bronx    NY 10020 USA

答案 1 :(得分:1)

您可以使用 sed 向特定位置插入空格:

 cat data.txt | sed -e 's#\(.\{13\}\)\(.*\)#\1 \2#g' | sed -e 's#\(.\{22\}\)\(.*\)#\1 \2#g' |sed -e '1s#\(.\{29\}\)\(.*\)#\1 \2#g' | sed -e '2,$s#\(.\{25\}\)\(.*\)#\1 \2#g' | sed -e 's#\(.\{31\}\)\(.*\)#\1 \2#g'

答案 2 :(得分:1)

您可以将字段长度拆分为数组,然后循环遍历$0并在常规awk中收集子字符串:

awk 'BEGIN {n=split("13 8 2 5 3",ar)} 
           {
             j=1
             s=""
             sep="\t" 
             for(i=1;i<n;i++) 
                 {s=s substr($0, j, ar[i]) sep; j+=ar[i]} 
             s=s substr($0, j, ar[i])
             print s
           }'   file

使用标签来分隔字段,但如果愿意,您也可以使用空格。