如何在许多文件中删除包含单词SID的一行?

时间:2009-08-12 23:56:32

标签: replace

如何删除许多文件中包含单词SID的一行?

我在sed和tr之间感到疑惑。但是,它们似乎都没有达到目的。 由于以下原因,我也希望有一些灵活性。

问题实际上更具挑战性。我需要在一些文件中匹配后删除一行,而在其他文件中删除一行。一行具有字符&,用于确定是删除一行以下还是仅删除一行。 最简单的方法是制作不同类型文件的列表,然后使用不同的代码删除每个列表中的文件。

数据示例

此处&

    . "question_sent"
    . "&"                        // I do not want this line
    .  htmlspecialchars(SID)     // NOT wanted
    . "&"
    . "email="

& 此处

    . "successful_registration&"
    . "SID="                    // Not wanted
    .  htmlspecialchars($SID)   // Not wanted
    . "&"                       // not wanted
    . "email="

字符&现在采用&

的HTML编码
  if(isset($_GET['ask_question'])) {
      echo  ("<li id='ask_question_active'><a href='?ask_question&amp;"
          .  htmlspecialchars(SID)   // not wanted
          . "&amp;"                 // not wanted
          . "email=

3 个答案:

答案 0 :(得分:3)

当代码如此不一致时,我不会觉得游戏会运行全局搜索和替换。我会使用grep / vim检查每一行,除非你认真做了10,000次更改。要使用grep / vim,步骤将是这样的:

1)将以下内容添加到.vimrc:

" <f1> looks for SID in the current file
map <f1> /\<SID\><CR>
" <f2> goes to the next file
map <f2> :next<CR><f1>

" <f5> deletes only the current line, and goes to the next SID
map <f5> dd
" <f6> deletes the current line and the one above, and goes to the next SID
map <f6> k2dd
" <f7> deletes the current line and the one below, and goes to the next SID
map <f7> 2dd
" <f8> deletes the current line, and the one above AND the one below
map <f8> k3dd

2)grep命令会找到您需要更改的所有文件:

grep -rl '\bSID\b' * > fix-these-files.txt

您可能需要稍微调整它以确保它找到您需要更改的所有文件。在进行下一步之前,请确保它是正确的。

3)使用vim打开需要修复的所有文件,如下所示:

vim '+set confirm' '+/\<SID\>' $(cat fix-these-files.txt)

4)您现在应该打开vim,并查看您需要更改的第一个文件中的第一个 SID 。使用以下步骤修复每次出现的SID:

  • 如果您只需要删除当前行,请按 <F5>
  • 如果您需要同时删除上述行,请按 <F6> ,而不是 <F5>
  • 如果您需要同时删除以下一行,请按 <F7> ,而不是 <F5>
  • 如果您需要同时删除下面上方的行,请按 <F8> 而不是 <F5>
  • <F1> 查找要修复的另一个 SID
  • 当在当前文件中找不到 SID 时,请按 <F2> 转到下一个文件。

当不再需要修复 SID 时退出vim。

5)通过再次从步骤(2)运行grep命令,检查以确保获得所有内容。应该没有搜索匹配。

6)删除您在步骤(1)中添加到.vimrc的额外映射。

警告:我没有测试过上述步骤,如果你使用它们,请注意你只做出你需要的更改!

答案 1 :(得分:2)

这不能用tr来完成。可能会使用Sed,但我不知道它是否足以举一个例子。我将使用的是perl,然后我可能会介绍一些状态变量,请参阅this answer以获取我的意思。可能我会使用状态single_ampersand_found(如果下一行包含SID,则不打印该行,忘记打印它)和SID_found(如果下一行包含&amp;忘记该行)。


更新:以下代码将禁止现在标记为“不想要”的所有行以及第一个示例中的第四行(即错误),但我认为它应该足以让您纠正并适应您的需要。

#!/usr/bin/perl -w
use strict;
use warnings;

my $state = 0;
my $state_ampersand_found = 1;
my $state_SID_found  = 2;

my $previous_line = "";

while (my $line = <>) {
        chomp($line);

        if ($line =~ /"&/) {
                if ($state == $state_ampersand_found) {
                        print $previous_line;
                }
                if ($state == $state_SID_found) {
                        $previous_line = "";
                        $state = 0;
                        next;
                }
                $state = $state_ampersand_found;
                # remember current line, but do not print it (yet)
                $previous_line = $line . "\n";
                next;
        }
        if ($line =~ /SID/) {
                $previous_line = "";
                $state = $state_SID_found;
                next;
        }
        $state = 0;
        print $previous_line;
        print $line, "\n";
}

答案 2 :(得分:1)

再次更新:我认为这修复了我发布的上一个脚本中的错误。

#!/usr/bin/perl

use strict;
use warnings;

my $re_amp = qr/"&(?:amp;)?"/;
my $re_sid = qr/SID/;

while ( my $this = <DATA> ) {
    next unless $this =~ /\S/;

    if ( $this =~ $re_amp ) {
        $this = skip_while(\*DATA, $re_sid);
    }
    elsif ( $this =~ $re_sid ) {
        $this = skip_while(\*DATA, $re_sid, $re_amp);
    }

    print $this if defined $this;
}

sub skip_while {
    my ($fh, $re1, $re2) = @_;
    my $line;
    while ( $line = <$fh> ) {
        next if (defined $re1 and $line =~ $re1)
             or (defined $re2 and $line =~ $re2);
        last;
    }
    return $line;
}

__DATA__
handlers/handle_new_question.php-        . "question_sent"
handlers/handle_new_question.php-        . "&"                        // I do not want this line
handlers/handle_new_question.php:        .  htmlspecialchars(SID)   // NOT wanted
handlers/handle_new_question.php-        . "&"
handlers/handle_new_question.php-        . "email="

handlers/handle_registration.php-            . "successful_registration&"
handlers/handle_registration.php:            . "SID="                   // Not wanted
handlers/handle_registration.php:            .  htmlspecialchars($SID)   // Not wanted
handlers/handle_registration.php-            . "&"                  // not wanted
handlers/handle_registration.php-//            . "email="

views/ask_question_link.php-        if(isset($_GET['ask_question'])) {
views/ask_question_link.php-            echo  ("<li id='ask_question_active'><a href='?ask_question&amp;"
views/ask_question_link.php:                .  htmlspecialchars(SID)   // not wanted
views/ask_question_link.php-                . "&amp;"           // not wanted
views/ask_question_link.php-//                . "email=

<强>输出:

C:\Temp> w
handlers/handle_new_question.php-        . "question_sent"
handlers/handle_new_question.php-        . "&"
handlers/handle_new_question.php-        . "email="
handlers/handle_registration.php-            . "successful_registration&"
handlers/handle_registration.php-//            . "email="
views/ask_question_link.php-        if(isset($_GET['ask_question'])) {
views/ask_question_link.php-            echo  ("<li id='ask_question_active'><a href='?ask_question&amp;"
views/ask_question_link.php-//                . "email=