如何使用 perl 或 awk 对文件中的数字执行数学运算?

Pao*_*ini 4 awk perl text-processing

我有一个文件A.txt:

RS0255_RS0083:115,124,129,141,143,168,170,180
RS0343_RS0083:112,113,163,175,181
RS0343_RS0255:94,101,107,164,179,183
Run Code Online (Sandbox Code Playgroud)

我想对以下数字执行数学运算:例如,我想为每个数字加 10:输出:

RS0255_RS0083:125,134,139,151,153,178,180,190
RS0343_RS0083:122,123,173,185,191
RS0343_RS0255:104,111,117,174,189,193
Run Code Online (Sandbox Code Playgroud)

我知道如何在 R 中执行此操作,但是如何对perl或中的文件中的数字执行此数学运算awk

ter*_*don 13

您可以使用数十种工具来对文本文件进行不同的操作。对于您提到的特定情况,我可能会使用 perl:

$ perl -pe 's/\b(\d+)\b/$1 + 10/ge' fileA.txt 
RS0255_RS0083:125,134,139,151,153,178,180,190
RS0343_RS0083:122,123,173,185,191
RS0343_RS0255:104,111,117,174,189,193
Run Code Online (Sandbox Code Playgroud)

  • @PaoloLorenzini,我会为 `s/pattern/repl/flags` 使用不同的分隔符,例如 `s:pattern:repl:flags` 或 `s{pattern}{repl}flags` (3认同)
  • @PaoloLorenzini 除法运算符 (`/`) 恰好等于替代 perl 命令中使用的分隔符 (`s/.../.../`)。为了能够在替换部分中使用该符号,请更改分隔符 (`s#...#...#`) 或转义字符 (`\/`)。`perl -pe 's#\b(\d+)\b#$1/10#ge' 文件` 或 `perl -pe 's/\b(\d+)\b/$1\/10/ge' 文件` (3认同)

row*_*oat 8

gawk '$0+0 == $0 {$0 += 10} {ORS = RT} 1' RS='[:,\n]' file
Run Code Online (Sandbox Code Playgroud)


Kus*_*nda 7

一个awk答案:分析每一行作为两个:-delimited领域。使用split()在第二场将其拆分成逗号领域,并且修改分裂场在一个循环中,创建一个新的输出记录。然后以逗号作为分隔符,并以原始第一个字段作为“前缀”输出新记录。

awk -F : '
    BEGIN { OFS = "," }
    {
        prefix = $1
        nf = split($2,a,",")
        $0 = ""

        for (i = 1; i <= nf; ++i)
            $i = a[i] + 10

        printf "%s:%s\n", prefix, $0
    }' fileA.txt
Run Code Online (Sandbox Code Playgroud)

输出将是

RS0255_RS0083:125,134,139,151,153,178,180,190
RS0343_RS0083:122,123,173,185,191
RS0343_RS0255:104,111,117,174,189,193
Run Code Online (Sandbox Code Playgroud)

上面代码的更简洁的表示(对于那些认为单行代码在某种程度上“更好”的人):

awk -F: '{p=$1;n=split($2,a,",");$0="";for(i=1;i<n;++i)$i=a[i]+10;printf "%s:%s\n",p,$0}' OFS=, fileA.txt
Run Code Online (Sandbox Code Playgroud)

较旧的答案,不如上面的“好”:

使用awk并将每一行解释为由:or分隔的字段列表,,将 10 添加到每行的第二个字段:

awk -F: '{p=$1;n=split($2,a,",");$0="";for(i=1;i<n;++i)$i=a[i]+10;printf "%s:%s\n",p,$0}' OFS=, fileA.txt
Run Code Online (Sandbox Code Playgroud)

这会给你

awk -F '[:,]' 'BEGIN { OFS="," } { for (i = 2; i <= NF; ++i) $i += 10 }; 1' fileA.txt
Run Code Online (Sandbox Code Playgroud)

要将每行的第一个逗号改回 a :,请使用sed 's/,/:/'

RS0255_RS0083,125,134,139,151,153,178,180,190
RS0343_RS0083,122,123,173,185,191
RS0343_RS0255,104,111,117,174,189,193
Run Code Online (Sandbox Code Playgroud)


αғs*_*нιη 5

awk -F, -v OFS=, '{
    split($1, tmp, ":");
    $1=tmp[1] ":" tmp[2]+10;
    for(i=2; i<=NF; i++ ) $i+=10;
}1' infile
Run Code Online (Sandbox Code Playgroud)