【问题标题】:sed: finding consecutive *similar* lines -- zip codessed:查找连续的*相似*行——邮政编码
【发布时间】:2012-01-19 04:57:32
【问题描述】:

我有一个地址文件,其中一些地址有两次城市邮编。

例子

Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909
TIMBUKTU, AK 99909

我想保留第一个,所以我认为像下面这样的 sed one-liner 可能会起作用:

sed -e '$!N' -e "s/\(.* 9[0-9]\{4\}\)\n.* 9[0-9]\{4\}/\1/" processme.txt

奇怪的是:它适用于没有空行的文件 --- 但不适用于有空行的文件。

???

想法?

【问题讨论】:

  • 您可以忽略我的回答,因为它使用了awk。我没有看到 sed only 标签。
  • 其实我只需要解决这个问题---awk 就可以了。我只是更熟悉 sed。旧的“如果你只有一把锤子……”综合症。
  • 听起来不错。 :) 我对答案又做了一个改动。您能否针对您的文件进行测试。
  • 你的 awk 语句也不起作用。
  • 我对一个示例文件进行了测试。如果你能告诉我问题是什么,那么我可以解决它。

标签: sed


【解决方案1】:

如果你还想使用sed

保留第一次出现

sed 'N;/9[[:digit:]]\{4\}\n.*9[[:digit:]]\{4\}/{P;d;D};P;D' processme.txt

保留第二次出现

sed 'N;/9[[:digit:]]\{4\}\n.*9[[:digit:]]\{4\}/D;P;D' processme.txt

此外,[[:digit:]] 的使用优于 [0-9],因为前者适用于不同的语言环境。

【讨论】:

  • 我想他想保留第一个地址而不是最后一个。
  • 是的,我想保留第一个。
  • @Bubnoff 好的,我更新了答案以适应任何一种情况。请注意,我的第一个答案保留第二次出现的唯一原因是因为这就是您接受的答案的作用。
  • 知道了,谢谢。我要对照我的记录检查一下,看看情况如何。
【解决方案2】:

更新以包含第一个匹配而不是第二个。

awk 'NF{a=$NF; b=$0; getline; if(a~$NF) {print b;next} else {print b; print $0; next}}1' file

输入文件:

[jaypal:~/Temp] cat file
Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909
TIMBUKTU, AK 99909

Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909
TIMBUKTU, AK 99909
Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909
TIMBUKTU, AK 99909

Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909
TIMBUKTU, AK 99909

输出:

[jaypal:~/Temp] awk 'NF{a=$NF; b=$0; getline; if(a~$NF) {print b;next} else {print b; 

print $0; next}}1' file
Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909

Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909
Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909

Joe Schmoe
4545 RANDOM ADDRESS ST NE
TIMBUKTU AK 99909

【讨论】:

  • 但线条不一样,只有相似。
  • 我需要匹配邮政编码。最后,我想在一个 shell 脚本中针对一组邮政编码运行它。
  • 是的,我只匹配最后一个字段,即zip code,如条件if (a==$NF) 所示。我修改为if(a~$NF)
  • 您尝试过最新版本吗?你遇到什么问题。我最近更新了答案以包括NF
  • 我的错误,您的 awk 语句正在工作。不知何故,城市邮编被复制了 3 到 4 次。它确实适用于双线 - 谢谢!我认为这也解释了我的 sed 语句的失败。
【解决方案3】:

这可能对你有用:

 sed ':a;$!N;/ \(9[0-9]\{4\}\)\n.*\(9[0-9]\{4\}\)/s/\n.*//;ta;P;D' file

这处理多个连续的相似行。 或者这样:

sed '/9[0-9]\{4\}/!b;:a;$!{N;/\n\s*$/ba};s/\(9[0-9]\{4\}\)\(\n\s*\)*[^\n]*9[0-9]\{4\}/\1/' file

这处理连续相似行之间的空白行。

sed ':a;$!{N;ba};s/\(9[0-9]\{4\}\)\(\n\s*\)*[^\n]*9[0-9]\{4\}/\1/;ta' file

这与多个连续的类似行一样,但会将整个文件吞入模式空间。

【讨论】:

  • 这是一个很难破译但我会试一试的。
猜你喜欢
  • 1970-01-01
  • 2012-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多