
Я разрабатываю скрипт, и он выполняет вычисления, которые нужно включить в уже заполненный текстовый файл. Формат строк файла:
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])