我想删除bibtex
文件中第一次出现的条目
根据其ID。例如,我们说我们有这个文件:
@inproceedings{id1,
author = "",
title = "",
...
}
@inproceedings{id2,
author = "",
title = "",
...
}
@misc{id1,
author = "",
title = "",
...
}
我想删除包含 id1 的第一个条目,因此我希望输出 是:
@inproceedings{id2,
author = "",
title = "",
...
}
@misc{id1,
author = "",
title = "",
...
}
我想要一种自动的方法,最好使用sed
。到现在为止我有这个:
sed '/^@.*{id1/, /}/d' input_file
但这会删除文件中的所有匹配项。你能帮我找个办法吗? 只删除第一个?
答案 0 :(得分:3)
这可能适合你(GNU sed):
sed 'x;/./{x;b};x;/^@.*{id1/,/}/{/}/h;d}' file
删除第一次出现后,在保留空间中设置一个标志,如果设置了标志,则忽略文件末尾的其他行。
编写sed命令时可以使用两个寄存器。 Sed将当前行(减去换行符)放置在Pattern Space(PS)中,第二个寄存器调用Hold Space(HS)。 x
交换HS的PS,h
将PS复制到HS。 sed一行脚本交换HS的PS,检查HS是否有任何字符/./
,如果这个条件为真,则重新密封HS的PS并退出。如果条件不为真,则为PS重新换行,并执行进一步的命令。查找范围条件/^@.*{id1/,/}/
,它是两个字符串之间包含的所有行,如果发现这些行被删除,但首先如果发现当前行是结束条件,则将该行复制到HS。 /}/h
。现在,后续行将被忽略到文件末尾。
答案 1 :(得分:1)
使用awk,您可以使用自定义RS
(记录分隔符)执行此操作:
awk -v RS= -v ORS='\n\n' '!/@inproceedings{id1/' f
@inproceedings{id2,
author = "",
title = "",
...
}
@misc{id1,
author = "",
title = "",
...
}
答案 2 :(得分:1)
sed '/^@inproceedings{id1,/,/}/ d' YourFile
删除该部分的每一行(/start/,/end/ action
)
答案 3 :(得分:1)
sed是单行上简单替换的优秀工具,但对于所有其他文本操作,你应该使用awk。
$ awk -v type="inproceedings" -v id="id1" -v RS= -v ORS='\n\n' -F'[@{,]' '!($2 == type && $3 == id)' file
@inproceedings{id2,
author = "",
title = "",
...
}
@misc{id1,
author = "",
title = "",
...
}
$ awk -v type="inproceedings" -v id="id2" -v RS= -v ORS='\n\n' -F'[@{,]' '!($2 == type && $3 == id)' file
@inproceedings{id1,
author = "",
title = "",
...
}
@misc{id1,
author = "",
title = "",
...
}
$ awk -v type="misc" -v id="id1" -v RS= -v ORS='\n\n' -F'[@{,]' '!($2 == type && $3 == id)' file
@inproceedings{id1,
author = "",
title = "",
...
}
@inproceedings{id2,
author = "",
title = "",
...
}
如果你想选择匹配的块而不是那些不匹配的块,只需在条件开始时删除!
。
所有用于操作多行代码块的sed语言构造(即除了s,g和p之外的所有内容都使用-n)在20世纪70年代中期被发明时已经过时了,因此只需忽略它们就像你一样永远不需要它们。获得由Arnold Robbins撰写的有效Awk编程,第三版,并花费你的时间。