Я новичок в Linux, так что это может быть ужасный совет, но единственное, что у меня сработало после того, как я попробовал более безопасные решения (изменение $ PATH и т. Д.) было «удалить» старую информацию об установке (переименовать ее).
> which install-info
/usr/bin/install-info
> mv /usr/bin/install-info install-info.bak
Думаю, это заставило его использовать новый.
После этого обновление прошло очень плавно.
Замена строк, имеющих 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
Ожидаются образцы исходных файлов, думаю, это должно сработать:
gawk '($1=="Count"){print "Count = " (++i); next;} 1' /tmp/rand_file1
Краткое пояснение:
в строках, имеющих Count
в качестве первого поля :напечатать новый оператор подсчета и увеличить число. ++i
начнется с 1, i++
начнется с 0. В этом случае также пропустите оставшуюся часть обработки и перейдите к строке ввода next
.
для всех строк(1
):выполнить действие по умолчанию, то есть распечатать строку ввода.
Это должно быть быстрее, так как оно затрагивает каждую строку ввода только один раз, в вашем существующем решении совпадение для Count
копирует весь файл.
Синтаксический анализ текстового файла в оболочке очень медленный и чрезвычайно подвержен ошибкам. Вы запускаете 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
См. также " Почему использование цикла оболочки для обработки текста считается плохой практикой? ".
Короткийawk
подход:
awk '$1 == "Count"{ $0 = "Count = "++i }1' file
Выход:
Count = 1
Name = Sarah
ID = 113
PhNo =
Count = 2
Name = John
ID = 787
PhNo =
Обязательный perl
ответ:
perl -pe 's{^Count\b.*}{"Count = ". ++$i}e'
Используя sed
,с seq
переданным для итерации:
t='Count'
seq -f "$t = %g" 70000 | sed -i -e "/^$t/R /dev/stdin" -e "/^$t/d" /tmp/rand_file1
Примечания:
sed
'sR
ead не будет работать в фигурных скобках {}
, поэтому необходимы две -e
s. 70000
может быть любым достаточно большим числом. Когда sed
останавливается, останавливается и seq
, так что более высокие значения даже не будут созданы.