簡體   English   中英

使用 bash 腳本(awk、sed 等)在兩個不同的列中正確地將數字更改為特定名稱

[英]Change numbers to specific name in properly step in two different columns by using bash script (awk, sed, etc)

我的輸入(我文檔的一小部分,我還必須在 100 個文檔上使用這個程序):

86834 SOL4504
86955 SOL5240
86963 SOL4251
SOL15 38222
SOL17 35642
SOL110 41053

我的 output:

MGD674 SOL4504
MGD675 SOL5240
MGD675 SOL4251
SOL15 MGD297
SOL17 MGD277
SOL110 MGD319

在我的程序中,我想將數字更改為特定名稱。 對於從 1 到 129 的數字,我將數字更改為名稱 MGD1(例如數字:1,名稱:MGD1;另一個示例數字:92,名稱:MGD1;另一個示例數字 12905,名稱:MGD101 等)。 我還必須在 100 個文件中執行此操作。

首先,我認為以這種方式執行此操作,但您可以創建完全不同的代碼:

#!/bin/bash
MGD_atom_index=1
number=1
MGD_mol_index=MGD$number
for index in {1..100} // I do this script on 100 files, that's why I use for loop
do
    for MGD_index in {1..900} //I run this 900 times for each file, because for every name (for example for every MGD1 program try to find and replace number, I will have max MGD900, because the highest number is 116100, so 116100/129 = 900.
    do
            sed -i "s/$MGD_atom_index/$MGD_mol_index/g;s/$(($MGD_atom_index+1))/$MGD_mol_index/g;s/$(($MGD_atom_index+2))/$MGD_mol_index/g.(this code will be very long, because I need write " s/$(($MGD_atom_index+2))/$MGD_mol_index/g" until I have $MGD_atom_index+128.....s/$(($MGD_atom_index+128))/$MGD_mol_index/g" new2_$index.ndx
        MGD_atom_index=$(($MGD_atom_index+129)) // I change atom index so for example first I look for numbers from 1 to 129 and change it to MGD1 and now I will find numbers from 130 to 258 and looking for MGD2
        number=$(($number+1))
        MGD_mol_index=SOL$number I change  and now I try to find and replace MGD2
    done
    MGD_atom_index=1 //here I reset all variables to one, because I will work on another file
    number=1
    MGD_mol_index=MGD$number
done

但是我有個問題,這段代碼會特別長,因為我需要寫這129次 s/$(($MGD_atom_index+x))/$MGD_mol_index/g; ,其中 x 是從 1 到 128 的數字),我也認為我的程序可能很慢。 也許有更好的方法來做到這一點?

我認為這 awk 就是您所需要的。

awk '
    $1~/^[0-9]+$/{$1="MDG" int($1/129+1)}
    $2~/^[0-9]+$/{$2="MDG" int($2/129+1)}
    1
' file
$ cat tst.awk
BEGIN { grp = 129 }
{
    for (i=1; i<=NF; i++) {
        if ( $i == ($i+0) ) {
            $i = "MGD" (int($i/grp)+1)
        }
    }
    print
}

$ awk -f tst.awk file
MGD674 SOL4504
MGD675 SOL5240
MGD675 SOL4251
SOL15 MGD297
SOL17 MGD277
SOL110 MGD319

所以你想要在 shell 腳本中使用 GNU awk 進行“就地”編輯:

#!/bin/env bash
awk -i inplace '
BEGIN { grp = 129 }
{
    for (i=1; i<=NF; i++) {
        if ( $i == ($i+0) ) {
            $i = "MGD" (int($i/grp)+1)
        }
    }
    print
}
' 'new2_'{1..100}'.ndx'

或與任何 awk 一起使用:

#!/bin/env bash
tmp=$(mktemp) || exit 1
for index in {1..100}; do
    awk '
    BEGIN { grp = 129 }
    {
        for (i=1; i<=NF; i++) {
            if ( $i == ($i+0) ) {
                $i = "MGD" (int($i/grp)+1)
            }
        }
        print
    }
    ' "new2_$index.ndx" > "$tmp" && mv "$tmp" "new2_$index.ndx"
done

這可能對您有用(GNU sed 和 bash):

sed -E 's#\b([0-9]+)\b#MGD$((\1/129+1))#g;s/.*/echo "&"/e' file

通過替換 shell 數值表達式,將所有數字組轉換為所需的格式,並在前面加上MGD ,然后使用 echo 命令計算表達式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM