【问题标题】:Want to edit a file in place (substitute a column value) based on a value in another column in the same file想要根据同一文件中另一列中的值就地编辑文件(替换列值)
【发布时间】:2012-09-16 19:31:11
【问题描述】:

我想根据同一文件中另一列中的值编辑文件(替换列值)。我不想在替换到另一个文件后重定向输出,而是想就地编辑文件。特别需要这个,因为需要编辑的文件不会被任何程序同时访问,因此必须进行就地编辑

我尝试了下面的代码。但这又是逐行写入输入文件

#!/usr/bin/perl -w

open(FILEIN, "/dummy/chaat/h2") || die("Cannot open file");
@file = <FILEIN>;
seek FILEIN, 0, 0;

foreach $file (@file) {
    @field = split(/\|/, $file);
    print $field[8] . "\n";
    if ($field[8] eq "ROBERT") {
        $file =~ s/JAMES/FUDIK/g;
        print FILEIN $file;
    }
}

我的示例记录如下所示。在这里,我想对此进行内联编辑。如果字段 8 是 ROBERT,则在字段 7 中将 JAMES 替换为 FUDIK

Change|sinmg|ewfewf|ewfew|def|fdfd|JAMES|rewr|ROBERT|dsf|fe
Change|sinmg|ewfewf|ewfew|def|JAMES|fewf|rewr|BEASLEY|dsf|fe

如果有任何帮助,我将不胜感激

【问题讨论】:

  • 除非新字段与前一个字段的大小完全相同,否则您无法避免重写文件,如果这是您的意图,请使用数据库。
  • @Thor 以下来自 TLP 的回答是有效的,与字段大小无关
  • -i 开关可能会说就地,但在后台使用了一个临时文件,请参阅perlrun(1)

标签: linux perl shell unix nawk


【解决方案1】:

这是一个 perl 单行代码:

perl -F'\|' -i -lape 'if ($F[8] eq "ROBERT") { s/JAMES/FUDIK/g }' /dummy/chaat/h2

-i 选项将进行就地编辑。您可能希望限制替换以避免部分匹配,例如:

s/(?<=\|)JAMES(?=\|)/FUDIK/g

或者您可以使用-n 开关而不是-p 并执行

s/JAMES/FUDIK/g for @F } print join "|", @F;

您应该知道,这种就地编辑实际上是在编写一个新文件,并复制旧文件。如果你想避免这种情况,你需要做一些认真的杂耍,并且可能在写入过程中锁定文件。

【讨论】:

  • 感谢您的回答。但是我尝试了上面的命令,这正在消失文件内容并使其为零字节。
  • @Chkusi 该命令无法截断您的文件。如果字段 8 是 ROBERT,它只会影响您的文件,然后只会将 JAMES 更改为 FUDIK。
  • 文件没有被修改。我已通过回答此问题显示日志。
  • 我忘了转义|,拆分后的字符串应该是\|。我已经更正了单行,它现在应该可以工作了。
  • 如果您认为它解决了您的问题,请不要忘记检查答案旁边的复选标记。
猜你喜欢
  • 2012-11-06
  • 2020-05-20
  • 1970-01-01
  • 2021-10-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-03
  • 2019-08-23
  • 2021-12-04
相关资源
最近更新 更多