Переименование нескольких файлов, содержащих разные номера

tac file |
awk -v string='apple1' -v replace='444444444' '
    !flag && $1 == string { $3 = replace; flag = 1 }
                          { print }' |
tac

Этот конвейер сначала меняет порядок строк в данных, используя tacиз GNU coreutils. Последняя строка, где 1-й столбец представляет собой определенную строку, легче найти таким образом.

Команда awkпросто сравнивает первый столбец с заданной строкой, и если мы еще не сделали замену(!flagне -ноль ), мы изменяем третий столбец, как только мы найти строку в 1-м столбце. При этом мы также устанавливаем flagв единицу, чтобы не производить дальнейших замен.

Остальная часть программы awkпросто печатает текущую строку (, включая измененную ).

В конце конвейера мы снова меняем порядок строк с помощью tac.

Результатом этого, учитывая данные в вопросе, является

apple1        10109283      20012983
apple1        10983102      10293809
apple1 10293893 444444444
apple10       109283019     109238901
apple10       192879234     234082034
apple10       234908443     3450983490

Столбцы в измененной строке немного отличаются от столбцов в других строках из-за модификации 3-го столбца. Чтобы он выглядел лучше, вы можете пропустить результат через дополнительную стадию column -tв конце конвейера. Если вы это сделаете, вывод будет выглядеть как

apple1   10109283   20012983
apple1   10983102   10293809
apple1   10293893   444444444
apple10  109283019  109238901
apple10  192879234  234082034
apple10  234908443  3450983490

с несколькими пробелами между столбцами.


С sedэто не так просто, как просто заменить 3-й столбец в первой строке, где строка встречается в 1-м столбце (, предполагая, что мы меняем местами строки данных, как в приведенном выше конвейере ). Мы также должны не заменять 3-й столбец в любых последующих строках, даже если 1-й столбец соответствует нашей строке.

Это sedсценарий редактирования, который делает это правильно (может быть любое количество его вариантов, которые могут работать):

/^apple1\>/ ! {
        p
        d
}

s/[[:digit:]]*$/444444444/

:loop
n
$ ! b loop

Первая часть заботится о печати строк в начале ввода, которые не соответствуют apple1в первом столбце.\>в выражении соответствует концу слова apple1, так что мы случайно не найдем apple10или apple12или любую другую подобную строку.p(print )иd(delete + continue со следующей строкой сверху скрипта )внутри {... }выполняются для каждой строки в начале ввода, которая не . ] соответствует выражению.

Команда s(замена )выполняется для первой строки ввода, в которой соответствует apple1в начале строки. Он просто заменяет строку цифр в конце строки на наши 4s.

Затем следует секция с меткой loop, которая заботится о передаче остальных данных без изменений путем печати текущей строки и чтения следующей строки с помощьюn(nвыполняет как печать, так и чтение ). «Текущая строка» будет изменена командой sпри первом проходе по этому циклу.

Самая последняя строка возвращается к метке loop, если мы еще не достигли последней строки ввода.

Пример запуска:

$ tac file | sed -f script.sed | tac
apple1        10109283      20012983
apple1        10983102      10293809
apple1        10293893      444444444
apple10       109283019     109238901
apple10       192879234     234082034
apple10       234908443     3450983490
0
01.09.2021, 21:15
0 ответов

Теги

Похожие вопросы