用于使用复杂模式重建部分不一致文件的bash/regex
我需要重建一个文件,将每一行分割成4段,并在每段之间插入一个像管道或:的分隔符。我的问题是结构有些不一致 该文件如下所示:用于使用复杂模式重建部分不一致文件的bash/regex,regex,bash,sed,awk,Regex,Bash,Sed,Awk,我需要重建一个文件,将每一行分割成4段,并在每段之间插入一个像管道或:的分隔符。我的问题是结构有些不一致 该文件如下所示: MIKE TESTUSER一些文本21-Etc BLA 43 BLA-Some,其他..12信息 STEVE NOBODY 43更多`文本等BLA(更多附加信息) 勒罗伊:有人再发一些短信吗 我需要把它分为姓名:地址:城市和可选的邮政编码:可选的附加信息 MIKE TESTUSER |一些文本21-等等| BLA43 BLA |-一些,附加..12信息 STEVE NOB
MIKE TESTUSER一些文本21-Etc BLA 43 BLA-Some,其他..12信息
STEVE NOBODY 43更多`文本等BLA(更多附加信息)
勒罗伊:有人再发一些短信吗
我需要把它分为姓名:地址:城市和可选的邮政编码:可选的附加信息
MIKE TESTUSER |一些文本21-等等| BLA43 BLA |-一些,附加..12信息
STEVE NOBODY | 43更多`文本等| BLA |(更多附加信息)
LEROY any |又是一些文本字符、数字|等等
第一段总是大写,没有数字或特殊字符
第二段由除大写单词以外的任何内容组成
第三段仅为大写字母,有时为数字
最后一段可以是除大写单词以外的任何内容
如果有人能解决这个问题,或者能为我指出一个让我接近的方向,那就太好了(不一定是完美的)
首先感谢您的快速回复!我尝试使用空格将每一行分解成数组元素,然后检查每个元素的大小写、数字等,有点像charlies-awk方法。问题是,我不能总是确定何时必须放置分隔符,因为一段有时以数字或非字母数字字符结尾,而下一段则以数字/非字母数字字符开头 比如说 姓名:23 Rue da guerre 321 12345马赛-信息 应该像 此名称|达格雷街23号321 | 12345马赛|-信息 这个文件有几千行,非常凌乱。通常是邮政编码 出现在城市的前面,有时在城市的后面,还有其他各种不一致之处 我知道在任何情况下都必须手动重新编辑,但我希望找到一个解决方案
使它不那么耗时:)它必须是bash吗?我会认真考虑写一些简单的Awk程序 比如说,作为一个开始
awk -f 'BEGIN {FS=" "; uplow=0;}
{uplow=1;
for(i=1; i < $NF; i++){
if(uplow && ($i ~ [A-Z])) out += $i+" "
else if (uplow && ($i !~ [A-Z])) {
uplow = 0;
out += "|"
} else if # fill in the other cases
}
print out
}'
awk-f'BEGIN{FS=”“;uplow=0;}
{uplow=1;
对于(i=1;i<$NF;i++){
如果(上传和($i~[A-Z])输出+=$i+“”
else if(uplow&($i!~[A-Z])){
uplow=0;
out+=“|”
}否则,请填写其他案例
}
打印出来
}'
其思想是检查每个空格分隔字段的大小写,并保留一个标记以记住您是在运行大写项目还是小写项目。更改的内容是将管道字符添加到输出中。您确实需要像Perl这样成熟的语言。应该是这样的:
使用严格;
使用警告;
打开我的文件“myFileName”或死亡qq(无法打开“myFileName”进行读取\n);
while(我的$line=){
chomp$行;
$line=~/([A-Z\s]+)(.*)([A-Z\d\s]{2,})(.*);
打印联接“|”,($1,$2,$3,$4)。“\n”;
}
最大的诀窍是正则表达式:
$line =~ /([A-Z\s]+)(.*)([A-Z\d\s])(.*);
这就是将行分成四个部分的原因(然后由$1
到$4
表示)。我没有足够的数据来测试它
你能在你的问题上附上大约4到5行的文件吗?我会解决一些问题的。这可能适合你:
sed 's/^\([A-Z ]*\) \(.*\)/\2\n\1|/;s/[A-Z]\{2\}/|&/;s/\([^|]*|\)\(.*\)/\2\1/;s/\([^A-Z0-9 ]\)/|\1/;s/\([^\n]*\)\n\(.*\)/\2\1/;s/|$//' file
到目前为止你试过什么?我们不应该从头开始为您编写此代码:-)您的规则有歧义:在上一个示例中,第二个分隔符可能位于
321
之前或12345
之后。