如何处理 linux 中具有固定宽度列的文件
How to process file having fixed width columns in linux
我要处理以下文件:
01234000000000000000000+000000000000000000+
02586000000000000000000+000000000000000000-
12345000000000000000000+000000000000000000-
12122000000000000000000+000000000000000000+
我想将以上文件转换为:
01234,000000000000000000+,000000000000000000+
02586,000000000000000000+,000000000000000000-
12345,000000000000000000+,000000000000000000-
12122,000000000000000000+,000000000000000000+
输入文件分别有固定宽度的列 5、19、19。
我想用linux命令解决。
我尝试了以下命令,但它不起作用:(
awk 'BEGIN{FIELDWIDTHS="5 19 19";OFS=",";}{=",,"}' data.txt
在 ubuntu 14.04 LTS 桌面 OS 上执行上述命令,输出为空(空白)。
那会很容易:
sed -n 's/\(.\{5\}\)\(.\{19\}\)\(.\{19\}\)/,,/p' your_file
它的作用是通过 5、19、19 捕获每一行,然后用 ,
将其打印出来。
$ echo 01234000000000000000000+000000000000000000+ | sed -n 's/\(.\{5\}\)\(.\{19\}\)\(.\{19\}\)/,,/p'
01234,000000000000000000+,000000000000000000+
您的尝试非常接近,尽管您忘记了 {print}
:
awk 'BEGIN{FIELDWIDTHS="5 19 19";OFS=","}{=}1' file
{=}
将第一个字段赋给自己,这足以使awk "touch" 每条记录。我使用了 shorthand 1
,这是最短的真实条件。默认操作是 {print}
.
请注意 FIELDWIDTHS
是 GNU awk 扩展,因此如果您使用不同的版本,则必须采用不同的方法。例如:
awk 'BEGIN{OFS=","}{print substr([=11=],1,5),substr([=11=],6,19),substr([=11=],25)}' file
Perl 来拯救:
perl -pe 'for $p (5, 25) { substr $_, $p, 0, "," }' data.txt
$ sed -r 's/(.{5})(.{19})/,,/' file
01234,000000000000000000+,000000000000000000+
02586,000000000000000000+,000000000000000000-
12345,000000000000000000+,000000000000000000-
12122,000000000000000000+,000000000000000000+
awk '{sub(/.0/,",0")sub(/+/,"+,")}1' file
0123,000000000000000000+,000000000000000000+
0258,000000000000000000+,000000000000000000-
1234,000000000000000000+,000000000000000000-
1212,000000000000000000+,000000000000000000+
这也是适合 cut
的任务
$ cut --output-delimiter=',' -c1-5,6-24,25- data.txt
01234,000000000000000000+,000000000000000000+
02586,000000000000000000+,000000000000000000-
12345,000000000000000000+,000000000000000000-
12122,000000000000000000+,000000000000000000+
--output-delimiter=','
指定输出字段分隔符
-c
至 select 指定字符
1-5
第一个字段
6-24
第二场
25-
其余行
我要处理以下文件:
01234000000000000000000+000000000000000000+
02586000000000000000000+000000000000000000-
12345000000000000000000+000000000000000000-
12122000000000000000000+000000000000000000+
我想将以上文件转换为:
01234,000000000000000000+,000000000000000000+
02586,000000000000000000+,000000000000000000-
12345,000000000000000000+,000000000000000000-
12122,000000000000000000+,000000000000000000+
输入文件分别有固定宽度的列 5、19、19。
我想用linux命令解决。
我尝试了以下命令,但它不起作用:(
awk 'BEGIN{FIELDWIDTHS="5 19 19";OFS=",";}{=",,"}' data.txt
在 ubuntu 14.04 LTS 桌面 OS 上执行上述命令,输出为空(空白)。
那会很容易:
sed -n 's/\(.\{5\}\)\(.\{19\}\)\(.\{19\}\)/,,/p' your_file
它的作用是通过 5、19、19 捕获每一行,然后用 ,
将其打印出来。
$ echo 01234000000000000000000+000000000000000000+ | sed -n 's/\(.\{5\}\)\(.\{19\}\)\(.\{19\}\)/,,/p'
01234,000000000000000000+,000000000000000000+
您的尝试非常接近,尽管您忘记了 {print}
:
awk 'BEGIN{FIELDWIDTHS="5 19 19";OFS=","}{=}1' file
{=}
将第一个字段赋给自己,这足以使awk "touch" 每条记录。我使用了 shorthand 1
,这是最短的真实条件。默认操作是 {print}
.
请注意 FIELDWIDTHS
是 GNU awk 扩展,因此如果您使用不同的版本,则必须采用不同的方法。例如:
awk 'BEGIN{OFS=","}{print substr([=11=],1,5),substr([=11=],6,19),substr([=11=],25)}' file
Perl 来拯救:
perl -pe 'for $p (5, 25) { substr $_, $p, 0, "," }' data.txt
$ sed -r 's/(.{5})(.{19})/,,/' file
01234,000000000000000000+,000000000000000000+
02586,000000000000000000+,000000000000000000-
12345,000000000000000000+,000000000000000000-
12122,000000000000000000+,000000000000000000+
awk '{sub(/.0/,",0")sub(/+/,"+,")}1' file
0123,000000000000000000+,000000000000000000+
0258,000000000000000000+,000000000000000000-
1234,000000000000000000+,000000000000000000-
1212,000000000000000000+,000000000000000000+
这也是适合 cut
的任务
$ cut --output-delimiter=',' -c1-5,6-24,25- data.txt
01234,000000000000000000+,000000000000000000+
02586,000000000000000000+,000000000000000000-
12345,000000000000000000+,000000000000000000-
12122,000000000000000000+,000000000000000000+
--output-delimiter=','
指定输出字段分隔符-c
至 select 指定字符1-5
第一个字段6-24
第二场25-
其余行