提取模式匹配项/从模式中除去行中的所有内容

时间:2019-05-29 07:49:16

标签: csv awk sed grep

我目前正在使用grep尝试从文件的每一行提取特定文本。它已成功提取出匹配项,但是,我希望它保留所有没有匹配项的行(将它们保留为空白行)。

这是我到目前为止尝试过的方法(在每一行上获取城市名称):

grep -o -P '(?<="city":").*?(?=")' input.txt

示例输入:

email":"addictedtotlick7@gmail.com","last_name":"THOMPSON","first_name":"ERIN",,"__v":0,,,,"state":"NY","city":"north tonawanda"}
first_name":"chris","last_name":"caul",,"email":"dawgzn@mail.com",,,,"__v":0}
email":"lesliebo993@hotmail.com",,"first_name":"LESLIE","last_name":"RAMBO",,"city":"DOTHAN","state":"AL",,,"__v":0,
email":"malala@yahoo.com",,,"state":"GA","city":"NORCROSS",,"last_name":"KEO","first_name":"CATHY",,"__v":0,
email":"kdela@gmail.com",,"state":"FL","city":"HOLLYWOOD",,"last_name":"DE LA CRUZ","first_name":"KIDA",,"__v":0,

所需的输出:

north tonawanda

DOTHAN
NORCROSS
HOLLYWOOD

如果更容易的话,也很乐意在SED中尝试某些操作,但是由于我必须处理大文件,并且不确定我是否有足够的RAM,所以宁愿避免使用AWK。

4 个答案:

答案 0 :(得分:0)

您可以使用GNU awk

gawk '{print index($0, "\"city\":\"") == 0 ? "" : gensub(/.*\"city\":\"([^\"]*).*/, "\\1", 1);}' file > newfile

这意味着:如果行中包含"city":"index($0, "\"city\":\"") == 0),则(?)打印空白行("")或(: )打印gensub(/.*\"city\":\"([^\"]*).*/, "\\1", 1)正则表达式替换的结果:

  • .*-任意0个以上的字符
  • \"city\":\"-一个"city":"子字符串
  • ([^\"]*)-捕获组1(\1):除"以外的任何0+个字符
  • .*-任意0个以上的字符。

其结果是组1的值。我们需要gensub,因此需要GNU awk,因为我们需要访问捕获组的值。

答案 1 :(得分:0)

Sed:

sed 's/.*city":"\([^"]*\).*/|\1/; /^[^|]/s/.*//; s/^|//'

答案 2 :(得分:0)

您可以尝试Perl

$ perl -nle ' if(/"city":"(.*?)"/) { print $1 } else { print "" } ' input.txt
north tonawanda

DOTHAN
NORCROSS
HOLLYWOOD

$

答案 3 :(得分:-1)

我建议另一个awk脚本

awk 'match($0,/(?<=\"city\":\").*?(?=\")/,m){$0=m[0]}1' input.txt

RAM和AWK没问题。

此脚本处理每一行。 如果当前行与RegExp (?<="city":").*?(?=")相匹配,则使用匹配项覆盖当前行。打印当前行。