我试图在文本文件中替换每个第n次出现的字符串。
背景: 我有一个巨大的bibtex文件(称为in.bib),包含以" @"开头的数百个条目。但每个条目都有不同的行数。我想写一个字符串(例如"#")就在每次(比如说)第6次出现" @"之前。所以,在第二步中,我可以使用 csplit 将大文件拆分为"#"到每个包含5个条目的文件中。
问题是找到并更换每五个" @"。
由于我需要反复,printing with sed or awk a line following a matching pattern中建议的答案不会完成。同样,我不是只寻找一个匹配的地方,而是寻找其中许多地方。
到目前为止我所拥有的:
awk '/^@/ && v++%5 {sub(/^@/, "\n#\n@")} {print > "out.bib"}' in.bib
替换第2次直到第5次出现(并且不再有)。 (顺便说一下,我在这里找到并采用了这个解决方案:" Sed replace every nth occurrence"。最初,它意味着取代每一次出现 - 它确实如此。)
而且,第二:
awk -v p="@" -v n="5" '$0~p{i++}i==n{sub(/^@/, "\n#\n@")}{print > "out.bib"}' in.bib
完全取代了第五次出现而没有别的。 (从这里采用的解决方案:" Display only the n'th match of grep"
我需要(而且不能写)是一个循环。 for循环可以完成这项工作吗?类似的东西:
for (i = 1; i <= 200; i * 5)
<find "@"> and <replace with "\n#\n@">
then print
我的材料看起来像这样:
@article{karamanic_jedno_2007,
title = {Jedno Kosova, Dva Srbije},
journal = {Ulaznica: Journal for Culture, Art and Social Issues},
author = {Karamanic, Slobodan},
year = {2007}
}
@inproceedings{blome_eigene_2008,
title = {Das Eigene, das Andere und ihre Vermischung. Zur Rolle von Sexualität und Reproduktion im Rassendiskurs des 19. Jahrhunderts},
comment = {Rest of lines snippet off here for usability -- as in following entries. All original entries may have a different amount of lines.}
}
@book{doring_inter-agency_2008,
title = {Inter-agency coordination in United Nations peacebuilding}
}
@book{reckwitz_subjekt_2008,
address = {Bielefeld},
title = {Subjekt}
}
我想要的是每个第六个条目,如下所示:
#
@book{reckwitz_subjekt_2008,
address = {Bielefeld},
title = {Subjekt}
}
感谢您的帮助。
答案 0 :(得分:0)
您的代码几乎是正确的,我修改了它。
要替换每第n次出现,您需要一个模块化表达式。
因此,为了更好地理解括号,您需要一个像((i % n) == 0)
awk -v p="@" -v n="5" ' $0~p { i++ } ((i%n)==0) { sub(/^@/, "\n#\n@") }{ print }' in.bib > out.bib
答案 1 :(得分:0)
您可以轻松地在awk
分步进行拆分。
awk -v RS='@' 'NR==1{next} (NR-1)%5==1{c++} {print RT $0 > FILENAME"."c}' file
将创建file.1,file.2等,每个记录包含5条记录,其中记录由分隔符@
定义。
答案 2 :(得分:0)
不要使用多个工具在多个步骤中执行此操作,只需执行以下操作:
awk '/@/ && (++v%5)==1{out="out"++c} {print > out}' file
未经测试,因为您没有提供任何样本输入/输出。
如果您没有GNU awk且输入文件很大,则需要在close(out)
之前添加out=...
,以避免同时打开太多文件。