如何使用多行搜索和替换多行

时间:2017-12-02 20:12:01

标签: bash perl awk sed grep

我查看了有关搜索和替换的其他答案,但我无法理解这些模式。

如何更改文件的这一部分(行号153 ... 156)

        let view = string.utf8
        offset.pointee += string.substring(to: range.lowerBound).utf8.count
        length.pointee = Int32(view.distance(from:range.lowerBound.samePosition(in: view), to:range.upperBound.samePosition(in: view)))
        return token

并将其替换为下面的行?

        let view:String.UTF8View = string.utf8

        if let from = range.lowerBound.samePosition(in: view),
           let to = range.upperBound.samePosition(in: view) {
            offset.pointee += Int32(string[string.startIndex..<range.lowerBound].utf8.count)
            length.pointee = Int32(view.distance(from: from, to: to))
            return token
        } else {
            return nil
        }

5 个答案:

答案 0 :(得分:4)

这可能适合你(GNU sed&amp; Bash):

sed $'153r replacementFile\n;153,156d' file

或大多数seds:

sed -e '153r replacementFile' -e '153,156d' file

或者如果您愿意:

sed '153,156c\        let view:String.UTF8View = string.utf8\
    if let from = range.lowerBound.samePosition(in: view),\
       let to = range.upperBound.samePosition(in: view) {\
        offset.pointee += Int32(string[string.startIndex..<range.lowerBound].utf8.count)\
        length.pointee = Int32(view.distance(from: from, to: to))\
        return token\
    } else {\
        return nil\
    }' file

N.B。第一个\保留前导空格,后面的每一行除了最后一行需要附加\。当空行由单个\表示时,SO中的降价格式不正确(因此我删除了替换的第二行),但大多数shell都应该。

答案 1 :(得分:2)

如果你没有获得@ karafka答案的GNU-sed,只想要在确切的行号上更改行,你也可以使用ed

ed -s file <<'EOF'
153,156c
        let view:String.UTF8View = string.utf8

        if let from = range.lowerBound.samePosition(in: view),
           let to = range.upperBound.samePosition(in: view) {
            offset.pointee += Int32(string[string.startIndex..<range.lowerBound].utf8.count)
            length.pointee = Int32(view.distance(from: from, to: to))
            return token
        } else {
            return nil
        }
.
w
q
EOF

答案 2 :(得分:1)

sed可能是最好的工具,

假设您的替换文本位于文件replace.txt

$ sed '153,156{153{r replace.txt
                  }; d}' file

可能仅适用于GNU sed

答案 3 :(得分:1)

这是Tie::File module应用程序的一个非常好的案例,它将数组映射到文本文件的行,以便您对数组所做的任何更改都将反映在磁盘文件中。它是一个核心模块,因此您不需要安装它。

此处,tie调用将数组@file映射到您的文本文件,并且 splice替换了从DATA读取的替换内容的四行文本。 然后untie更新并关闭文件。

请注意,您必须将myfile.txt更改为输入文件的实际路径。

use strict;
use warnings 'all';

use Tie::File;

tie my @file, 'Tie::File', 'myfile.txt' or die $!;

splice @file, 152, 4, <DATA>;

untie @file;



__DATA__
        let view:String.UTF8View = string.utf8

        if let from = range.lowerBound.samePosition(in: view),
           let to = range.upperBound.samePosition(in: view) {
            offset.pointee += Int32(string[string.startIndex..<range.lowerBound].utf8.count)
            length.pointee = Int32(view.distance(from: from, to: to))
            return token
        } else {
            return nil
        }

答案 4 :(得分:1)

Perl one-liner,用于更改153..156中内容为file的内容repl.file,就地

perl -i -wpe'
    if   (153..155) { s/.*\n// }
    elsif ($.==156) { local $/; open $fh, "repl.file"; $_ = <$fh> };    
' file

(或$_ = path($file_name)->slurpPath::Tiny。)

这可以直接转换为脚本,可以通过写出带有更改的新文件并将其移到原始文件上(参见in perlfaq5和SO帖子),也可以通过脚本中的using -i ($^I)移动。