Закомментируйте все вхождения, кроме первого, используя sed

Плохие блоки не удалялись, так как я видел, как клон диска читал плохие блоки при записи на новый диск. Сами плохие блоки помечены. Затем эти плохие блоки необходимо перепроверить и пометить как чистые с помощью инструмента для исправления, например. fsck, ntfsfixили другие. Однако это фантомные плохие блоки, а не настоящие плохие блоки. Это, однако, доказывает идею о том, что они должны быть зафиксированы, чтобы быть удаленными. Изменение размера не должно очищать метки, и полное форматирование этого раздела должно создавать для них новые маркеры местоположения. Что касается того, куда он будет указывать после операции, я не могу вспомнить. Однако это можно проверить, как сказал agc.

-1
07.05.2020, 21:22
7 ответов

По крайней мере, с GNU sed (, который у вас должен быть по умолчанию в Ubuntu ), вы можете использовать диапазоны адресов, такие как 0,/pattern/. Так что, возможно, что-то вроде:

$ sed '0,/^two/!s//#&/' original.txt 
one
two
three
#two
#two
#two

Это говорит: «Для каждой строки, кроме строк между строкой 0 и первым совпадением /^two/, замените /^two/на #, за которым следует то, что вы только что сопоставили. Пустой шаблон //в подстановке соответствует предыдущему регулярное выражение, а &заменяет только что совпадающую вещь -версия без -гольфа будет

sed '0,/^two/!s/^two/#two/' original.txt

Так как ^twoпривязан к началу строки, он не соответствует уже закомментированному вхождению -, если это не то , что вам нужно, удалите ^.

4
28.04.2021, 23:15
perl -p -i -e '$_ = ("#" x $count{$_}++). $_' your-file

дает ожидаемый результат. Он добавляет к каждой строке столько префиксов #, сколько было вхождений одной и той же строки ранее.

Опция -iвыше редактирует файл i n -место (на самом деле опция -iнайденная в некоторых реализациях sedвроде вашей была скопирована изperl).

1
28.04.2021, 23:15

Это не совсем то, что вам может понадобиться, но, если я правильно понимаю, вы хотите получить файл, в котором незакомментированные записи уникальны, а все остальное прокомментировано. Я не знаю, как вы это сделаете, но один обходной путь — сохранить исходный файл в неприкосновенности и в итоге получить другой файл с уникальными файлами...

$ cat sample.txt | uniq | grep -v ^#  
one
three
two
0
28.04.2021, 23:15

Использование edвместо sedдля редактирования файла:

printf "%s\n" '/^two/+1,$g/^two/s/^two/#two/' w | ed -s sample.txt

Для каждой строки, начинающейся сtwoпосле первой такой строки до конца файла, (Диапазон адресов /^two/+1,$), поставьте #впереди.

0
28.04.2021, 23:15

Используя Posix sed, мы можем выполнить преобразование следующим образом:

$ sed -e '
    /^two$/!b
    H;g;s/^\(\n\n*\).*/\1/;x
    s/.//;y/\n/#/
' file

Выход:

one
two
three
#two
##two
#two

Пояснение:

Для интересных строк /^two$/ мы ставим префикс новой строки, сохраняем новые строки в удержании, удаляем одну новую строку и превращаем оставшиеся новые строки в хэши.

И если мы не хотим накапливать хэши, мы можем использовать приведенный ниже код posixly:

$ sed -e '
    /^two$/!b
    :a;n;s//#&/;ba
' file
one
two
three
#two
#two
#two
0
28.04.2021, 23:15

Так как мы отключились sedвот awkвариант

awk '/^two/{if (t) printf "#";t++}1'  file

Просто установите флаг при первом совпадении и printf "#"при каждом последующем совпадении до естественного вывода

0
28.04.2021, 23:15

sedобщеизвестно, что он плохо считает. Сawk:

проще
$ awk '/^two/ { if (++count > 1) $0 = "#" $0 }; 1' file
one
two
three
#two
#two
#two

Это добавляет символ #к каждой строке, начинающейся со строки two, после того, как первая проигнорирована одна такая строка. Все строки, модифицированные или нет, затем печатаются (через конечный 1в коде, который можно заменить на{ print }).

1
28.04.2021, 23:15

Теги

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