如何在 sed 中执行这种替换?

如何在 sed 中执行这种替换?

我有这样的文字:

Table {\label{seq:ref176}} - Table name.




\begin{longtable}{|m{3.36636in}|m{3.36636in}|}

我想像这样编辑它:

\begin{longtable}{|m{3.36636in}|m{3.36636in}|}
\caption{Table name \label{seq:ref176}}\\

Atom我可以这样做:

寻找:Table \{\\label\{(.*?)\}\} - (.*?).\n*\\begin\{longtable\}\{(.*?)\|\}

代替:\begin{longtable}{$3|}\n\\caption {$2 \\label{$1}}\\\\

我尝试在 sed 中执行此操作,但不起作用。没有错误。只是找不到任何匹配项。

s/Table\ \{\\label\{(.*?)\}\}\ \-\ (.*?)\n*\\begin\{longtable\}\{(.*?)\|\}/\\begin\{longtable\}\{\3\|\}\n\\caption\ \{\2\ \\label\{\1\}\}\\\\/g

答案1

如果 Perl 单行程序是一种选择,请尝试:

perl -0777 -pe 's/Table \{(\\label\{.*?\}\}) - (.*?)\.\s+(\\begin\{longtable\}\{.*?\|\})/$3\n\\caption{$2 $1/' file
\begin{longtable}{|m{3.36636in}|m{3.36636in}|}
\caption{Table name \label{seq:ref176}}

答案2

您的尝试有一个概念性错误和一个小错误。

其概念sed是逐行处理文件(默认情况下)。幸运的是,如果传递了参数,GNU sed 可以对整个文件进行处理-z

小修改是\.为了得到想要的结果而添加缺失的部分。我不会责怪你,因为当表达式又长又乱的时候,很难发现这些微小的东西。

命令行:

sed -rz 's/Table\ \{\\label\{(.*?)\}\}\ \-\ (.*?)\.\n*\\begin\{longtable\}\{(.*?)\|\}/\\begin\{longtable\}\{\3\|\}\n\\caption\ \{\2\ \\label\{\1\}\}\\\\/g' file

输出:

\begin{longtable}{|m{3.36636in}|m{3.36636in}|}
\caption {Table name \label{seq:ref176}}\\

参考来自 GNU sed文档

'-z'
'--null-data'
'--zero-terminated'
     Treat the input as a set of lines, each terminated by a zero byte
     (the ASCII 'NUL' character) instead of a newline.  This option can
     be used with commands like 'sort -z' and 'find -print0' to process
     arbitrary file names.

答案3

python我更喜欢用而不是来编写脚本sed,因为用 python 处理整个文件更容易。

#!/usr/bin/python

import re
import argparse


def test_regex(input):
    with open(input) as f:
        data = f.read()

    file = open("output.tex","w") 
    file.write(data)
    file.close() 

    data = re.sub(r'Table \{\\label\{(.*?)\}\} - (.*?).\s*\\begin\{longtable\}\{(.*?)\|\}',
                  r'\\begin{longtable}{\3|}\n\\caption {\2 \\label{\1}}\\\\', data)

    file = open("output.tex","w") 
    file.write(data)
    file.close() 


def main(input):
    test_regex(input)

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument("input")
    args = parser.parse_args()
    input = args.input
    main(input)

相关内容