sed 命令删除与模式匹配的行块(上方和下方)(sed) - 使用 Python 重新定义



参考以下链接

从json文件中删除json对象的Python脚本

由于我对";sed";,我有一个文件(my_file.json(,其内容如下;并且我需要删除从"0"开始的所有行;{"最多"},";。

[
{
"use":"abcd",
"contact":"xyz",
"name":"my_script.py",
"time":"11:22:33"
},
{
"use":"abcd"
"contact":"xyz",
"name":"some_other_script.py",
"time":"11:22:33"
},
{
"use":"apqwkndf",
"contact":"xyz",
"name":"my_script.py",
"time":"11:22:33"
},
{
"use":"kjdshfjkasd",
"contact":"xyz",
"name":"my_script.py",
"time":"11:22:33"
}
]

我使用了以下命令;它帮助我删除块的下部,即在图案till"}之后"以及具有图案的线条和上方的线条。

sed -i '/my_script.py"/I,+2 d;$!N;/my_script.py"/!P;D' my_file.json

输出如下

[
{
"use":"abcd",
{
"use":"abcd"
"contact":"xyz",
"name":"some_other_script.py",
"time":"11:22:33"
},
{
"use":"apqwkndf",
{
"use":"kjdshfjkasd",
]

预期输出为;请注意,因为它只剩下一个块,所以我需要删除"也

[
{
"use":"abcd"
"contact":"xyz",
"name":"some_other_script.py",
"time":"11:22:33"
}
]

我该如何解决这个问题?

这可能对你有用(GNU sed(:

sed '/{/{:a;N;/}/!ba;/my_script.py/d}' file |
sed 'N;/]/s/},/}/;P;D'

这将删除不需要的列表元素,然后修复最后一个列表分隔符。

另一种选择是将编辑后的文件存储在内存中,然后修复最后一个分隔符:

sed '/{/{:a;N;/}/!ba;/my_script.py/d};H;$!d;x;s/.//;s/(.*}),(s*])/12/' file

你能在一个awk中尝试以下操作吗?像json这样的公平警告输入文件应该由类似jq的工具编辑或读取,因为OP说他不允许使用它,所以添加它。它完全由显示的样本编写。

awk '
/{/{
found=1
if(noPrint==""){
actualVal=(actualVal?actualVal ORS:"")val
}
val=noPrint=""
}
found && /"name":"my_script.py"/{
noPrint=1
}
{
val=(val?val ORS:"")$0
}
END{
if(noPrint==""){
actualVal=(actualVal?actualVal ORS:"")val
}
sub(/},$/,"}n]",actualVal)
print actualVal
}
'  Input_file 

处理此类问题的常用方法:

  1. 包输入。通常每行转换为一个包含的信息
  2. 过滤输入
  3. 输出

以下脚本:

cat <<EOF |
[
{
"use":"abcd",
"contact":"xyz",
"name":"my_script.py",
"time":"11:22:33"
},
{
"use":"abcd",
"contact":"xyz",
"name":"some_other_script.py",
"time":"11:22:33"
},
{
"use":"apqwkndf",
"contact":"xyz",
"name":"my_script.py",
"time":"11:22:33"
},
{
"use":"kjdshfjkasd",
"contact":"xyz",
"name":"my_script.py",
"time":"11:22:33"
}
]
EOF
sed -n '
b noterror ; : error {
s/.*/ERROR: &/
q1
} ; : noterror
# remove [ ]
1d;$d;
# first line should be open braces
/{/!{b error}
# read up until closing brackets
# Note escaping is not handled
: again {
N;
$b error
/}/!b again
}
s/}.*/}/;
s/n/ /g;
# -- one information per line --
p
' | awk '
# filter that myscript.py with a regex
!/"name" *: *"my_script.py"/{
# output with those [ ]
printf "[n"
print # print the line
printf "]n"
}'

输出:

[
{                 "use":"abcd",                 "contact":"xyz",                 "name":"some_other_script.py",                 "time":"11:22:33"              }
]

您可能希望通过将一个特殊字符放在换行符的位置,然后将该字符替换回换行符,或者为awk使用不同的分隔符来恢复换行符至.

最新更新