Заменить поле счетчика в большом файле повторяющимся значением

Я новичок в Linux, так что это может быть ужасный совет, но единственное, что у меня сработало после того, как я попробовал более безопасные решения (изменение $ PATH и т. Д.) было «удалить» старую информацию об установке (переименовать ее).

> which install-info
/usr/bin/install-info
> mv /usr/bin/install-info install-info.bak

Думаю, это заставило его использовать новый.

После этого обновление прошло очень плавно.

0
20.04.2018, 17:57
6 ответов

Замена строк, имеющих Count, на Count = его вхождению

Предполагая, что Count является первым словом в строке

awk -v c=1 'sub(/^Count.*/, "Count = " c) {c++}; {print}' /tmp/rand_file1

Предполагая, что Count является первым словом в строке, но ему может предшествовать ноль или более пробелов, пробелы не сохраняются.

awk -v c=1 'sub(/^[[:blank:]]*Count.*/, "Count = " c) {c++}; {print}' /tmp/rand_file1
1
28.01.2020, 02:13

Ожидаются образцы исходных файлов, думаю, это должно сработать:

gawk '($1=="Count"){print "Count = " (++i); next;} 1' /tmp/rand_file1

Краткое пояснение:

  • в строках, имеющих Countв качестве первого поля :напечатать новый оператор подсчета и увеличить число. ++iначнется с 1, i++начнется с 0. В этом случае также пропустите оставшуюся часть обработки и перейдите к строке ввода next.

  • для всех строк(1):выполнить действие по умолчанию, то есть распечатать строку ввода.

Это должно быть быстрее, так как оно затрагивает каждую строку ввода только один раз, в вашем существующем решении совпадение для Countкопирует весь файл.

0
28.01.2020, 02:13

Синтаксический анализ текстового файла в оболочке очень медленный и чрезвычайно подвержен ошибкам. Вы запускаете grepодин раз для каждой строки входного файла и sedдважды для каждой строки, содержащей Count. Избегайте этого.

Насколько я понимаю, это можно заменить на

awk '$1 == "Count" { printf("Count = %d\n", ++i); next } { print }' rand_file1 >rand_file1.new

Это выводит Count =строк с правильным приращением, когда встречается строка, чье первое поле точно равно Count, и пропускает все остальные строки как -.

Как вариант,

awk '$1 == "Count" { $0 = sprintf("Count = %d", ++i) } { print }' rand_file1 >rand_file1.new

который изменяет значение $0(входной строки )и печатает все строки с одним print.

Этот последний вариант можно сократить до

awk '$1 == "Count" { $0 = sprintf("Count = %d", ++i) } 1' rand_file1 >rand_file1.new

См. также " Почему использование цикла оболочки для обработки текста считается плохой практикой? ".

3
28.01.2020, 02:13

Короткийawkподход:

awk '$1 == "Count"{ $0 = "Count = "++i }1' file

Выход:

Count = 1
Name = Sarah
ID = 113
PhNo =

Count = 2
Name = John
ID = 787
PhNo =
3
28.01.2020, 02:13

Обязательный perlответ:

perl -pe 's{^Count\b.*}{"Count = ". ++$i}e'
2
28.01.2020, 02:13

Используя sedseqпереданным для итерации:

t='Count'
seq -f "$t = %g" 70000 | sed -i -e "/^$t/R /dev/stdin" -e "/^$t/d" /tmp/rand_file1

Примечания:

    Команда
  • sed'sRead не будет работать в фигурных скобках {}, поэтому необходимы две -es.
  • 70000может быть любым достаточно большим числом. Когда sedостанавливается, останавливается и seq, так что более высокие значения даже не будут созданы.
1
28.01.2020, 02:13

Теги

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