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

Я новый пользователь Ubuntu. Пожалуйста, помогите мне в решении следующей проблемы:

Мой входной текстовый файл

    -0.716425 -12.8939 -3.3341 -7.38497 -2.62709 3.00437
    -6.69861 -13.8853 -5.81095 -7.37465 -0.268193 -5.45344

Мой выходной текстовый файл должен выглядеть

    1:-0.716425 2:-12.8939 3:-3.3341 4:-7.38497 5:-2.62709 6:3.00437
    7:-6.69861 8:-13.8853 9:-5.81095 10:-7.37465 11:-0.268193 

Я старался sed команда, но не получил требуемых результатов.

Как мне это сделать из командной строки?

3 ответа

$ cat file
-0.716425 -12.8939 -3.3341 -7.38497 -2.62709 3.00437
-6.69861 -13.8853 -5.81095 -7.37465 -0.268193 -5.45344
$ awk '{for (i=1;i<=NF;i++)printf "%s:%s%s",++n,$i,OFS;print""}' file
1:-0.716425 2:-12.8939 3:-3.3341 4:-7.38497 5:-2.62709 6:3.00437 
7:-6.69861 8:-13.8853 9:-5.81095 10:-7.37465 11:-0.268193 12:-5.45344 

Как это устроено

  • for (i=1;i<=NF;i++)printf "%s:%s%s",++n,$i,OFS

    Это зацикливает каждое поле в строке и печатает его с добавленным числом. Переменная n это номер. ++n приращений n по одному каждый раз, когда он вызывается.

  • print""

    Это печатает новую строку в конце каждой строки.

Чтобы обновить файл на месте

awk '{for (i=1;i<=NF;i++)printf "%s:%s%s",++n,$i,OFS;print""}' file >file.tmp && mv file.tmp file

Или с новейшими версиями GNU awk (4.1.0+, в Ubuntu 14.10+):

gawk -i inplace '{for (i=1;i<=NF;i++)printf "%s:%s%s",++n,$i,OFS;print""}' file

Как насчет python:

#!/usr/bin/env python2
with open('/path/to/file.txt') as f:
    prev = 0
    for line in f:
        elements = line.rstrip().split()
        for i in range(len(elements)):
            print str(prev + i + 1) + ':' + elements[i],
        print '\n'.rstrip()
        prev = len(elements)

Выход:

1:-0.716425 2:-12.8939 3:-3.3341 4:-7.38497 5:-2.62709 6:3.00437 
7:-6.69861 8:-13.8853 9:-5.81095 10:-7.37465 11:-0.268193 12:-5.45344

Если вы хотите сохранить выходные данные в тот же файл, вы должны сначала сохранить выходные данные во временный файл, затем удалить исходный файл и затем переименовать временный файл в исходный файл.

Если вы используете GNU awk (gawk), вы можете сделать это с помощью умного разделения записей:

awk '{ORS=RT; print NR":"$0}' RS='[ \n]+' infile

Выход:

1:-0.716425 2:-12.8939 3:-3.3341 4:-7.38497 5:-2.62709 6:3.00437
7:-6.69861 8:-13.8853 9:-5.81095 10:-7.37465 11:-0.268193 12:-5.45344
Другие вопросы по тегам