Измените числа, указав c имя в соответствующем шаге в двух разных столбцах, используя скрипт bash (awk, sed, et c) - PullRequest
1 голос
/ 07 апреля 2020

Мой ввод (очень маленькая часть моего документа, и я также должен использовать эту программу на 100 документах):

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

Мой вывод:

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

В моей программе, Я хочу изменить номер на конкретное c имя. Для номера от 1 до 129 я меняю номер на имя MGD1 (например, номер: 1, имя: MGD1; другой номер примера: 92, имя: MGD1; еще один номер примера 12905, имя: MGD101, et c.) , Я также должен выполнить эту операцию в 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), и я также думаю, что моя программа может быть медленной. Может быть, есть лучший способ сделать это?

Ответы [ 3 ]

1 голос
/ 07 апреля 2020
$ 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

так что вы хотите в своем скрипте оболочки это 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
1 голос
/ 08 апреля 2020

Это может работать для вас (GNU sed и bash):

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

Преобразовать все группы чисел в требуемый формат, подставив выражение оболочки нумерации c, которому предшествует MGD и затем вычисление выражения с помощью команды echo.

1 голос
/ 07 апреля 2020

Я думаю, что это все, что вам нужно.

awk '
    $1~/^[0-9]+$/{$1="MDG" int($1/129+1)}
    $2~/^[0-9]+$/{$2="MDG" int($2/129+1)}
    1
' file
...