Unix 使用正则表达式设置文本文件格式

Unix 使用正则表达式设置文本文件格式,unix,Unix,我正在尝试格式化一个下面的文本文件,记录顺序总是这样 Dept 0100 Batch Load Errors for 8/16/2016 4:45:56 AM Case 1111111111 Rectype: ABCD Key:UMUM_REF_ID=A12345678,UMSV_SEQ_NO=1 UMSV ERROR :UNITS_ALLOW must be > or = UNITS_PAID Case 2222222222 Rectype: ABCD

我正在尝试格式化一个下面的文本文件,记录顺序总是这样

Dept 0100 Batch Load Errors for 8/16/2016 4:45:56 AM 

Case 1111111111
Rectype: ABCD 
    Key:UMUM_REF_ID=A12345678,UMSV_SEQ_NO=1
        UMSV ERROR  :UNITS_ALLOW must be > or = UNITS_PAID 

Case 2222222222
Rectype: ABCD 
    Key:UMUM_REF_ID=B87654321,UMSV_SEQ_NO=2
        UMSV ERROR  :UNITS_ALLOW must be > or = UNITS_PAID 
        NTNB ERROR  :Invalid Value                       NTNB_MCTR_SUBJ=AMOD

Case 3333333333
Rectype: WXYZ 
    Key:UMUM_REF_ID=U19817250,UMSV_SEQ_NO=2
        UMSV ERROR  :UNITS_ALLOW must be > or = UNITS_PAID 
作为输出

1111111111~ABCD~UMUM_REF_ID=A12345678,UMSV_SEQ_NO=1~UMSV ERROR  :UNITS_ALLOW must be > or = UNITS_PAID
2222222222~ABCD~UMUM_REF_ID=B87654321,UMSV_SEQ_NO=2~UMSV ERROR  :UNITS_ALLOW must be > or = UNITS_PAID|NTNB ERROR  :Invalid Value NTNB_MCTR_SUBJ=AMOD
3333333333~WXYZ~UMUM_REF_ID=U19817250,UMSV_SEQ_NO=2~UMSV ERROR  :UNITS_ALLOW must be > or = UNITS_PAID
我尝试了正则表达式,如下所示

sed -r '/^Case/!d;$!N;/\nRectype/!D;s/\s+$/ /;s/(.*)\n(.*)/\2\1\n\1/;P;D' file.txt
但这只能工作到重新键入行,无法实现rest


谢谢。

在我看来,您并不是在寻找正则表达式。您正在寻找文本重新格式化,并且似乎已在sed中选择正则表达式匹配作为处理字段的方法

了解。谢天谢地,您已经包含了原始数据和预期输出,这对于新的StackOverflow成员来说是非常棒的。(真的!你太棒了!)所以我可以推荐一种可能更适合你的替代方案

真糟糕。另一个命令行工具,如sed,几乎安装在地球上所有类似unix的系统上

$ awk -v RS= -v OFS="~" '!/^Case/{next} {sub(/^Key:/,"",$5); key=$5; for (f=6;f<=NF;f++) { if ($f=="NTNB") key=key "|"; else if ($f=="UMSV") key=key OFS; else key=key " "; key=key $f } print $2,$4,key}' inp2
1111111111~ABCD~UMUM_REF_ID=A12345678,UMSV_SEQ_NO=1~UMSV ERROR :UNITS_ALLOW must be > or = UNITS_PAID
2222222222~ABCD~UMUM_REF_ID=B87654321,UMSV_SEQ_NO=2~UMSV ERROR :UNITS_ALLOW must be > or = UNITS_PAID|NTNB ERROR :Invalid Value NTNB_MCTR_SUBJ=AMOD
3333333333~WXYZ~UMUM_REF_ID=U19817250,UMSV_SEQ_NO=2~UMSV ERROR :UNITS_ALLOW must be > or = UNITS_PAID
在您的情况下,只需运行:

$ od -c filename | less
(如果缺少,则使用
more
。)

许多系统都有一个名为
dos2unix
的软件包,可以转换文本格式

如果您没有可用的
dos2unix
,您应该能够使用其他工具实现同样的功能。在GNU sed中:

sed -i 's/\r$//' filename
或者在其他sed变体中,但使用支持格式替换的shell(如bash)(阅读
mansed
查看是否有
-i
选项):

或者更精确一点,因为它将删除所有CR,即使它们不在行的末尾,您可以使用
tr

tr -d '\015' < inputfile > outputfile

祝你好运

在我看来,您并不是在寻找正则表达式。您正在寻找文本重新格式化,并且似乎已在sed中选择正则表达式匹配作为处理字段的方法

了解。谢天谢地,您已经包含了原始数据和预期输出,这对于新的StackOverflow成员来说是非常棒的。(真的!你太棒了!)所以我可以推荐一种可能更适合你的替代方案

真糟糕。另一个命令行工具,如sed,几乎安装在地球上所有类似unix的系统上

$ awk -v RS= -v OFS="~" '!/^Case/{next} {sub(/^Key:/,"",$5); key=$5; for (f=6;f<=NF;f++) { if ($f=="NTNB") key=key "|"; else if ($f=="UMSV") key=key OFS; else key=key " "; key=key $f } print $2,$4,key}' inp2
1111111111~ABCD~UMUM_REF_ID=A12345678,UMSV_SEQ_NO=1~UMSV ERROR :UNITS_ALLOW must be > or = UNITS_PAID
2222222222~ABCD~UMUM_REF_ID=B87654321,UMSV_SEQ_NO=2~UMSV ERROR :UNITS_ALLOW must be > or = UNITS_PAID|NTNB ERROR :Invalid Value NTNB_MCTR_SUBJ=AMOD
3333333333~WXYZ~UMUM_REF_ID=U19817250,UMSV_SEQ_NO=2~UMSV ERROR :UNITS_ALLOW must be > or = UNITS_PAID
在您的情况下,只需运行:

$ od -c filename | less
(如果缺少,则使用
more
。)

许多系统都有一个名为
dos2unix
的软件包,可以转换文本格式

如果您没有可用的
dos2unix
,您应该能够使用其他工具实现同样的功能。在GNU sed中:

sed -i 's/\r$//' filename
或者在其他sed变体中,但使用支持格式替换的shell(如bash)(阅读
mansed
查看是否有
-i
选项):

或者更精确一点,因为它将删除所有CR,即使它们不在行的末尾,您可以使用
tr

tr -d '\015' < inputfile > outputfile

祝你好运

所需输出的第二行中的空格似乎比相应输入行中的空格长。这是有意的吗?@Beta:我刚刚更新了所需的输出,如果有需要,需要修剪额外的空格。
Key:
的连接规则是什么?第一行和第二行是由
~
分隔的字段,后续行与
|
连接?还是以
N
开头的行总是与
|
和其他所有的
~
连接?还是别的什么?所有大于2个空格的字符串都应该缩小到2,还是可以缩小到1?所需输出的第二行中的空格似乎比相应输入行中的空格长。这是有意的吗?@Beta:我刚刚更新了所需的输出,如果有需要,需要修剪额外的空格。
Key:
的连接规则是什么?第一行和第二行是由
~
分隔的字段,后续行与
|
连接?还是以
N
开头的行总是与
|
和其他所有的
~
连接?还是别的什么?所有大于2个空格的字符串应该缩小为2,还是可以缩小为1?感谢您提出的解决方案,它对我在这里提到的文件格式非常有效(我手动创建了这个示例文件)。但当我在另一个具有相同格式和相同字段标记的文件上运行此代码时,并没有得到期望的结果。我试图运行的代码文件是由Windows操作系统创建的,因此可能存在一些垃圾值,而不是空格和新行。很遗憾,我不能在这里上传文件。有没有什么方法我可以确定它到底包含什么,这样我就可以格式化它,使这个代码工作。很高兴这有帮助。是的,你一针见血——我添加了一个更新,而不是在评论中添加解释和解决方案。哇!!运行您提供的命令后,我可以在文件中看到许多\r\n。我删除了\r并运行了您的解决方案。一切都成功运行。还需要一个帮助。我用文件(超过10000条记录)运行代码,在单元测试期间,我意识到,文件中也有没有以空行结尾的记录(两个“Case”记录之间没有空行)。因为这两条记录被连接在一起。我尝试在代码中更改“RC=\n”而不是“NULL”,但不起作用。不,将
RC
设置为空值是导致Awk在多行记录模式下运行的魔法。正如
gawk
手册页所说:““如果RS设置为空字符串,则记录用空行分隔。当RS设置为空字符串时,换行符始终充当字段分隔符”。感谢您提出的解决方案,它对于我在这里提到的文件格式非常有效(我手动创建了此示例文件)。但当我在另一个具有相同格式和相同字段标记的文件上运行此代码时,并没有得到期望的结果。我试图运行的代码文件是由Windows操作系统创建的,因此可能存在一些垃圾值,而不是空格和新行。很遗憾,我不能在这里上传文件。有没有什么方法我可以确定它到底包含什么,这样我就可以格式化它,使这个代码工作。很高兴这有帮助。是的,你