Редактирование файлов с помощью скрипта оболочки

Редактирование файлов с помощью скрипта оболочки

Я разрабатываю скрипт, и он выполняет вычисления, которые нужно включить в уже заполненный текстовый файл. Формат строк файла:

1 20/10/16 12:00 take car in the garage joe's garage

Внутри скрипта я получаю число из вычислений, и это число заменит первое число строки. Например, "calculate" возвращает значение 15, затем скрипт должен получить доступ к файлу и изменить строку, это должно выглядеть так:

15 20/10/16 12:00 take car in the garage joe's garage

Дело в том, что я не знаю, как это изменить. Это может быть в bash, awk, sed или любом доступном ресурсе. Спасибо.

решение1

Как насчет:

awk -v old=$oldNum -v new=$newNum \
'{if ($1==old) {$1=new; print} else {print}}' input.txt > output.txt

Попробовал так:

$ cat input.txt
2 19/10/16 15:30 some other line
1 20/10/16 12:00 take car in the garage joe's garage
3 17/10/16 5:30 another one

$ oldNum=2
$ newNum=15

Запустите команду awk, затем:

$ cat output.txt
15 19/10/16 15:30 some other line
1 20/10/16 12:00 take car in the garage joe's garage
3 17/10/16 5:30 another one

Это то, что вы хотели? Если вы хотите, чтобы ваш результат появился в исходном файле, просто mvвыходной файл с новым именем input.txt, который должен перезаписать входной файл (используйте антислеш, \mvчтобы избежать псевдонимов команды mv).

ПРИМЕЧАНИЕ: вы, вероятно, можете получить тот же результат с помощью более коротких инструкций awk, но этот синтаксис делает его более читабельным. sedВероятно, можно сделать это еще более лаконично.


EDIT: Я понимаю, что это работает, если вы хотите изменить только 1 число в вашем файле. Если я правильно понял вашу проблему, вы хотите пересчитать число длякаждыйline и создайте файл с этими новыми числами. Оптимальным способом сделать это было бы включить ваш расчет нового номера строкивнутрискрипт awk, таким образом, вам не придется создавать цикл оболочки, что, как правило, плохая идея, поскольку вызов инструментов типа awk, echo, sed... многократно оказывается очень затратным. Вы можете сделать что-то вроде этого:

if [ -f $PWD/output.txt ]; then 
    # Remove old output if present in current directory
    \rm -f $PWD/output.txt
fi

awk '{ ###calculation here, result store in newNum###; $1=newNum; print}' input.txt > output.txt

Например, если я хочу просто тривиально увеличивать на единицу номер каждой строки:

awk '{$1++; print}' input.txt > output.txt

Если вы не можете (или не осмелитесь) включить свои вычисления внутрь awk, вы можете сделать цикл по файлу, но это довольно неуклюже, насколько я понимаю в bashнаписании скриптов:

if [ -f $PWD/output.txt ]; then 
    # Remove old output if present in current directory
    \rm -f $PWD/output.txt
fi

while read line
do
    newNum=###Calculation here for current line###
    echo $line | awk -v new=$newNum '$1=new' >> output.txt
done <input.txt

решение2

попробуй это..

awk -v num="$variable" '{$1=num}1' input.txt

решение3

Вот короткий скрипт на Python, который делает то, что вам нужно. Использование простое: дайте ему файл, номер, с которого начинается строка, и номер, который вы хотите видеть вместо этого

Демонстрация:

    bash-4.3$ cat data.txt
    2 19/10/16 15:30 какая-то другая строка
    1 20/10/16 12:00 отвезти машину в гараж в гараж Джо
    3 17/10/16 5:30 еще один
    bash-4.3$ python renumber.py data.txt 1 15
    ['renumber.py', 'data.txt', '1', '15']
    bash-4.3$ cat data.txt
    2 19/10/16 15:30 какая-то другая строка
    15 20/10/16 12:00 отвезти машину в гараж Джо Гараж
    3 17/10/16 5:30 еще один

Код:

import sys
import os

print(sys.argv)

with open(sys.argv[1]) as inputfile:
    with open('/tmp/temp.text','w') as tempfile:
         for line in inputfile:
             old = line.strip().split()
             if old[0] == sys.argv[2]:
                old[0] = sys.argv[3] 
                line = ' '.join(old) + '\n' 
             tempfile.write(line)

os.rename('/tmp/temp.text',sys.argv[1])

Связанный контент