如何使用sed或awk去除一组行或块?

时间:2017-04-10 17:18:20

标签: unix awk sed

我正在运行OSX。我可以使用什么命令行工具?我有一个带有这个JSON输出的大文本文件。我正在寻找一种方法来剥离那些email而没有last_login_date的{​​{1}},我对没有它的记录不感兴趣。这是输出:

{
        "_id" : ObjectId("52fba903e4b0aa6226e0ce26"),
        "email" : "bar@foo.com"
}
{
        "_id" : ObjectId("521ca254e4b0d28eb6a07f26"),
        "email" : "foo@bar.com",
        "last_login_date" : ISODate("2017-04-10T14:27:03.212Z")
}

sed或awk是否为此候选人?如果是这样,你能告诉我如何剥离文件:

{
        "_id" : ObjectId("52fba903e4b0aa6226e0ce26"),
        "email" : "bar@foo.com"
}

2 个答案:

答案 0 :(得分:1)

如果记录完全是您描述它们的方式,那么您可以使用:

grep last_login_date -B 3 -A 1 yourFile.json > out.json

基本上对你感兴趣的东西进行捣乱,并在模式之前保留3行,之后保持1行。

答案 1 :(得分:1)

如果输入是正确的JSON,使用第三方CLI jq将是正确的工具 - 见底部。
鉴于不是这样,必须使用常规的文本处理实用程序。

neric's answer适用于macOS附带的BSD grep,但依赖于非常具体的文件布局。

awk 允许更灵活的解决方案(仍然假设输入中的JSON对象不是嵌套,不过):

awk -v RS='{' '/"last_login_date"/ { print RS $0 }' file
  • -v RS='{'将输入记录分隔符RS设置为{,这意味着一次只读取一个类似JSON的对象(没有前导{ 1}})。

  • 正则表达式匹配模式/"last_login_date"/在每条记录中查找子字符串"last_login_date",并仅在找到时执行相关操作({...})。

  • print "{" $0 }只需打印匹配的记录,并重新添加前导{

如果输入是正确的JSON ,使用 jq 会使处理更强大和简洁

jq 'select(.last_login_date)' file

上面只选择(过滤)输入文件中那些具有last_login_date属性(其值不是布尔false)的JSON对象。