【问题标题】:If column 1 is a match, change value of column 3 using Awk如果第 1 列匹配,则使用 Awk 更改第 3 列的值
【发布时间】:2018-05-10 07:17:14
【问题描述】:

我必须编辑一个大文件,其中每条记录的列不是由字符分隔而是具有固定长度。我想在第一列中搜索一个值,如果找到,请更改第三列的值。

我无法将文件从它所在的位置取出,所以我只能使用带有 awk、sed 和 java 5 的命令行。否则我会尝试其他解决方案。

bigfile.dat 结构:

Column1Col2Column3Column4Col5

例子:

id12345TEXTVALUE01SOMCODETEXT
id23456TEXTVALUE02SOMCODETEXT
id34567TEXTVALUE02SOMCODETEXT
id45678TEXTVALUE01SOMCODETEXT
id56789TEXTVALUE03SOMCODETEXT

我需要什么:为 id45678 设置 VALUE04

id12345TEXTVALUE01SOMCODETEXT
id23456TEXTVALUE02SOMCODETEXT
id34567TEXTVALUE02SOMCODETEXT
id45678TEXTVALUE04SOMCODETEXT
id56789TEXTVALUE03SOMCODETEXT

我不知道这是否可能。这是一些我认为可能可以与 awk 一起使用的伪代码:

if (match id = subtr(Column1))
print subtr(Column1+Col2) + "mychange" +substr(Column4+Col5)
else
print unchanged line

我不是要求为我做我的工作,我只是不知道我在用我拥有的工具浪费我的时间,或者我只是缺乏知识。

谢谢。

【问题讨论】:

    标签: awk sed ksh


    【解决方案1】:

    使用awk,这实际上很容易做到:

    pax: awk <input.txt '/^id45678/{$0=substr($0,1,11)"VALUE04"substr($0,19)}1'
    id12345TEXTVALUE01SOMCODETEXT
    id23456TEXTVALUE02SOMCODETEXT
    id34567TEXTVALUE02SOMCODETEXT
    id45678TEXTVALUE04SOMCODETEXT
    id56789TEXTVALUE03SOMCODETEXT
    

    它只查找以id45678 开头的行并修改您想要更改的那部分行。

    末尾的1 只是一个打印行的命令,无论是否更改(这是一个“技巧”,使用真值1 来选择(默认)打印行的操作)。

    【讨论】:

    • 这非常有效。它看起来非常简单,但事实是我要花很长时间才能到达那里。非常感谢。
    【解决方案2】:

    将 GNU awk 的 FIELDWIDTHS 用于固定宽度字段:

    $ awk '
    BEGIN {
        FIELDWIDTHS="7 4 7 7 4"  3  # set the field widths
        OFS=""                      
    }
    $1=="id45678" {                 # when the first field has the given value
        $3="VALUE04"                # replace the third field
    }1' file                        # output
    Column1Col2Column3Column4Col5
    id12345TEXTVALUE01SOMCODETEXT
    id23456TEXTVALUE02SOMCODETEXT
    id34567TEXTVALUE02SOMCODETEXT
    id45678TEXTVALUE04SOMCODETEXT
    id56789TEXTVALUE03SOMCODETEXT
    

    【讨论】:

    • 这是一个非常棒的功能,我不知道,当然值得一票。
    • 这更干净,不幸的是我们有一个较旧的 awk 版本。谢谢。
    【解决方案3】:

    使用 GNU sed:

    sed -E 's/^(id45678....)......./\1VALUE04/' file
    

    或更短:

    sed -E 's/^(id45678.{4}).{7}/\1VALUE04/' file
    

    和变量:

    s="id45678"
    r="VALUE04"
    sed -E 's/^('"$s"'.{4}).{7}/\1'"$r"'/' file
    

    输出:

    id12345TEXTVALUE01SOMCODETEXT id23456TEXTVALUE02SOMCODETEXT id34567TEXTVALUE02SOMCODETEXT id45678TEXTVALUE04SOMCODETEXT id56789TEXTVALUE03SOMCODETEXT

    如果您想“就地”编辑文件,请使用 sed 的选项 -i

    【讨论】:

    • 我不知道旧版 sed 是否有任何等效的解决方案,因为这个不支持 -E 也不支持 -i。幸运的是,awk 解决方案奏效了。谢谢。
    • 如果没有-E,其中一个可以工作:sed 's/^\(id45678....\)......./\1VALUE04/'sed -r 's/^(id45678.{4}).{7}/\1VALUE04/' file
    猜你喜欢
    • 2015-11-30
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多