Bash文本文件格式

时间:2014-03-07 03:10:33

标签: bash shell unix awk

我有一些文件格式如下:

555584280113;01-04-2013 00:00:11;0,22;889;30008;1501;sms;/xxx/yyy/zzz
552185022741;01-04-2013 00:00:13;0,22;889;30008;1501;sms;/xxx/yyy/zzz
5511965271852;01-04-2013 00:00:14;0,22;889;30008;1501;sms;/xxx/yyy/zzz
5511980644500;01-04-2013 00:00:22;0,22;889;30008;1501;sms;/xxx/yyy/zzz
553186398559;01-04-2013 00:00:31;0,22;889;30008;1501;sms;/xxx/yyy/zzz
555584280113;01-04-2013 00:00:41;0,22;889;30008;1501;sms;/xxx/yyy/zzz
558487839822;01-04-2013 00:01:09;0,22;889;30008;1501;sms;/xxx/yyy/zzz

我需要在开头有一个10位数字的序列,删除第二列上的前缀55(我用简单的sed's / ^ 55 // g'完成)并重新格式化日期看起来像这样:

0000000001;555584280113;20130401 00:00:11;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000002;552185022741;20130401 00:00:13;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000003;5511965271852;20130401 00:00:14;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000004;5511980644500;20130401 00:00:22;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000005;553186398559;20130401 00:00:31;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000006;555584280113;01-04-2013 00:00:41;0,22;889;30008;1501;sms;/xxx/yyy/zzz

我有一个单独的日期部分:

cat file.txt | cut -d\; -f2 | awk '{print $1}' |awk -v OFS="-" -F"-" '{print $3$2$1}'

它有效,但我不知道如何将所有这些放在一起,序列+ sed为前缀+更改日期格式。顺序部分我甚至不知道该怎么做。

感谢您的帮助。

3 个答案:

答案 0 :(得分:6)

awk是用于文本解析和格式化的最佳工具之一。这是满足您要求的一种方式:

awk '
BEGIN { FS = OFS = ";" }
{
    printf "%010d;", NR
    $1 = substr($1,3)
    split($2, tmp, /[- ]/)
    $2=tmp[3]tmp[2]tmp[1]" "tmp[4]
}1' file

  • 我们将输入和输出字段分隔符设置为;
  • 我们使用printf格式化您的第一个列号要求
  • 我们使用substr函数删除第1列的前两个字符
  • 我们使用split函数格式化时间
  • 使用1我们按原样打印其余语句。

<强>输出:

0000000001;5584280113;20130401 00:00:11;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000002;2185022741;20130401 00:00:13;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000003;11965271852;20130401 00:00:14;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000004;11980644500;20130401 00:00:22;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000005;3186398559;20130401 00:00:31;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000006;5584280113;20130401 00:00:41;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000007;8487839822;20130401 00:01:09;0,22;889;30008;1501;sms;/xxx/yyy/zzz

答案 1 :(得分:2)

如果输入文件的名称为input,则以下命令将删除55,添加10位数的行号,并重新排列日期。使用GNU sed

 nl -nrz -w10 -s\; input | sed -r 's/55//; s/([0-9]{2})-([0-9]{2})-([0-9]{4})/\3\2\1/'

如果您正在使用Mac OSX(或其他没有GNU sed的操作系统),则需要稍作修改:

 nl -nrz -w10 -s\; input | sed -E 's/55//; s/([0-9]{2})-([0-9]{2})-([0-9]{4})/\3\2\1/'

示例输出:

0000000001;5584280113;20130401 00:00:11;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000002;2185022741;20130401 00:00:13;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000003;11965271852;20130401 00:00:14;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000004;11980644500;20130401 00:00:22;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000005;3186398559;20130401 00:00:31;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000006;5584280113;20130401 00:00:41;0,22;889;30008;1501;sms;/xxx/yyy/zzz
0000000007;8487839822;20130401 00:01:09;0,22;889;30008;1501;sms;/xxx/yyy/zzz

工作原理: nl是一个方便的* nix实用程序,用于添加行号。 -w10告诉nl我们需要10位数的行号。 -nrz告诉nl用零填充行号,-s\;告诉nl在行号后添加分号。 (我们必须转义分号,以便shell忽略它。)

其余更改由sed处理。 sed命令s/55//删除了55的第一次出现。日期的重新安排由s/([0-9]{2})-([0-9]{2})-([0-9]{4})/\3\2\1/处理。

答案 2 :(得分:0)

您实际上可以使用Bash循环来执行此操作。

i=0
while read f1 f2; do
    ((++i))
    IFS=\; read n d <<< $f1
    d=${d:6:4}${d:3:2}${d:0:2}
    printf "%010d;%d;%d %s\n" $i $n $d $f2
done < file.txt