【问题标题】:I need to alter lines of a unix file that contain a certain string我需要更改包含某个字符串的 unix 文件的行
【发布时间】:2014-05-07 08:13:16
【问题描述】:

我有一个使用定界符的带有固定格式行的文件。我想在第三个字段中识别所有带有字符串“密码”的行并将它们编辑出来。如,在它们的开头放一个“#”。 我还想删除第四个字段的现有值。 我不知道该怎么做。看起来应该可以分两步完成,但我无法解决。我正在使用 unix shell,所以 SED、AWK 等。 该文件的示例行是:

database2|~|t1||~|${topuser.username}|~|topuser
database2|~|t1||~|${topuser.password}|~|H4rdt0Gu3ss
database2|~|t1||~|${loguser.username}|~|LOG
database2|~|t1||~|${loguser.password}|~|Ih4v3n01d34y0utry
# database2|~|t1||~|${open.var1}|~|connect
database2|~|t1||~|${tablespace}|~|gis_tbs1

有些可能已经被编辑掉了,分隔符是“|~|”。 请帮忙。

【问题讨论】:

    标签: linux shell sed awk ksh


    【解决方案1】:

    这是一个实现目标的 Perl 脚本:

    #!/usr/bin/perl
    
    use warnings;
    use strict;
    
    while (<DATA>) {
        chomp;
        my @fields = split /\|~\|/;
        if ($fields[2] =~ /password/) {
            $fields[0] = "# $fields[0]";
            $fields[3] = '';
        }
        print join("|~|", @fields), "\n";
    }
    
    __DATA__
    database2|~|t1||~|${topuser.username}|~|topuser
    database2|~|t1||~|${topuser.password}|~|H4rdt0Gu3ss
    database2|~|t1||~|${loguser.username}|~|LOG
    database2|~|t1||~|${loguser.password}|~|Ih4v3n01d34y0utry
    # database2|~|t1||~|${open.var1}|~|connect
    # database2|~|t1||~|${tablespace}|~|gis_tbs1
    

    这里是单行版本:

    perl -F'/\|~\|/' -ane '$"="|~|"; if ($F[2] =~ /password/) { $F[0]="# $F[0]"; $F[3] = "\n"; } print "@F";' datafile
    

    【讨论】:

    • 单行:perl -lpe '@F=split /\|~\|/; $F[0]="# $F[0]" and $F[3]="" if $F[2]=~/password/; $_=join "|~|", @F' file:)
    • 感谢您的宝贵时间。 :) 非常感谢。
    【解决方案2】:

    如果我正确理解了您的问题,那么以下内容应该有效:

    $ awk 'BEGIN{FS=OFS="\|"}$6~/password/{$6="# "$6;$NF=""}1' file
    database2|~|t1||~|${topuser.username}|~|topuser
    database2|~|t1||~|# ${topuser.password}|~|
    database2|~|t1||~|${loguser.username}|~|LOG
    database2|~|t1||~|# ${loguser.password}|~|
    # database2|~|t1||~|${open.var1}|~|connect
    database2|~|t1||~|${tablespace}|~|gis_tbs1
    

    如果您的意思是通过将 # 放在行首编辑它们,那么您可以这样做:

    $ awk 'BEGIN{FS=OFS="\|"}$6~/password/{$NF="";$0="# "$0}1' file
    database2|~|t1||~|${topuser.username}|~|topuser
    # database2|~|t1||~|${topuser.password}|~|
    database2|~|t1||~|${loguser.username}|~|LOG
    # database2|~|t1||~|${loguser.password}|~|
    # database2|~|t1||~|${open.var1}|~|connect
    database2|~|t1||~|${tablespace}|~|gis_tbs1
    

    【讨论】:

    • 所以我搞砸了我的样本数据。添加了一个额外的|。应该是这样的。数据库2|~|t1|~|${topuser.username}|~|topuser 数据库2|~|t1|~|${topuser.password}|~|用过这个,谢谢。猫 t | awk '开始 {FS=OFS="|"} $5 ~ /password/ { $7=""; printf("#%s\n", $0) }; $5 !~ /password/ {print $0}'
    • @Sparkle 你可以改用awk 'BEGIN{FS=OFS="\|"}$5~/password/{$NF="";$0="# "$0}1' file 这个。简短而简单。
    • OP:如果你想要平等,而不是包容,请将~ 更改为==。您的问题不清楚您是要准确查找“密码”,还是要查找字段值中任何位置的子字符串。
    猜你喜欢
    • 1970-01-01
    • 2011-06-26
    • 2015-09-27
    • 2022-11-25
    • 1970-01-01
    • 2017-07-11
    • 2014-09-22
    • 2022-06-10
    • 1970-01-01
    相关资源
    最近更新 更多