Форум русскоязычного сообщества Ubuntu


Хотите сделать посильный вклад в развитие Ubuntu и русскоязычного сообщества?
Помогите нам с документацией!

Автор Тема: Удаление дублирующихся строк и непосредственное изменение в файле с помощью sed  (Прочитано 942 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн alex-sky

  • Автор темы
  • Участник
  • *
  • Сообщений: 158
    • Просмотр профиля
Существует файл в котором продублированы строки.
  Необходимо сверить с эталонной строкой и удалить все строки, оставив нужную строку

Вот исходный текст.

(Нажмите, чтобы показать/скрыть)

Вот что смог только сделать

(Нажмите, чтобы показать/скрыть)

Символ табуляции \t в регулярном выражении не заменяет символа \s*, поэтому
указывая образец точного поиска приходится в скрипте использовать клавишу TAB.
 Скрипт который смог сделать удаляет только часть строк.

Может кто знает более удобное решение

« Последнее редактирование: 30 Июнь 2017, 11:58:47 от alex-sky »

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2628
    • Просмотр профиля
Символ табуляции \t в регулярном выражении не заменяет символа \s*, поэтому
заменяет
(Нажмите, чтобы показать/скрыть)

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Необходимо сверить с эталонной строкой и удалить все строки, оставив нужную строку
Читается как абсолютный бред. Покажите на приведенном примере что Вы хотите видеть в результате.
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн alex-sky

  • Автор темы
  • Участник
  • *
  • Сообщений: 158
    • Просмотр профиля
Оставить только такую строку

  workgroup = WORKGROUP,

вместо пробела знак табуляции перед найденной строкой


Пользователь добавил сообщение 30 Июнь 2017, 16:07:03:
Цитировать
заменяет

Вот что имею ввиду

grep -x "^\tworkgroup = WORKGROUP" ./file.conf

или

grep -x "^\s*workgroup = WORKGROUP" ./file.conf

не находят искомую строку, то есть строку перед которой стоит символ табуляции.

grep -x - поиск точного вхождения указанного шаблона, это мне и нужно


« Последнее редактирование: 30 Июнь 2017, 16:09:48 от alex-sky »

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2628
    • Просмотр профиля

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
Оставить только такую строку
  workgroup = WORKGROUP
sed '/workgroup\s*=/{/^\tw.* = \bWORKGROUP\b/! d}'
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн ReNzRv

  • Старожил
  • *
  • Сообщений: 2628
    • Просмотр профиля
(Нажмите, чтобы показать/скрыть)

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
renzrv, скорее всего это конфиг, и там должны быть, подозреваю, другие параметры, кроме workgroup и их надо оставить. Во-вторых, на всякий случай, я бы использовал тогда …WORKGROUP\s*$
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

Оффлайн alex-sky

  • Автор темы
  • Участник
  • *
  • Сообщений: 158
    • Просмотр профиля
grep -Px '\tworkgroup = WORKGROUP' ./file.conf

Да спасибо.

Цитировать
-P, --perl-regexp         ШАБЛОН - регулярное выражения языка Perl

Сам бы я не понял, что здесь нужен вот такой ключ.(я перебирал ключи и возможно что-то не правильно сделал, поэтому и не получалось)

Пользователь добавил сообщение 03 Июль 2017, 17:22:49:
renzrv, скорее всего это конфиг

да, это для конфигурационных файлов


sed '/workgroup\s*=/{/^\tw.* = \bWORKGROUP\b/! d}'


Удаляет все строки, кроме указанной в шаблоне, если будут обнаружены строки идентичные шаблону то они останутся.
 И удаляет пустую строку сразу после последней оригинальной (что не совсем  удобно).

Поясните пожалуйста некоторые моменты :

/workgroup\s*=/ - шаблон, для поиска вхождения, которое нужно заменить
 шаблон состоит из – эталонного слова - workgroup-, после этого слова ищется
\s*=       - любое количество пробельных символов до знака равно.
^\tw.*    – от начала строки, найти символ табуляции, одну букву – w –
.* =      - найти любое количество символов, кроме символа переноса строки (\n )
= \b    - после знака равно найти символ пробела и далее стоит якорь «граница слова»

 Почему здесь решили использовать якорь?

\bWORKGROUP\b

! – для чего он здесь?
d – это флаг для удаления строки

Не могли бы написать по какому шаблону составлено это выражение.
 Например, как я вижу

sed '/шаблон/{/замена/! d}' - ???

Но я нигде не видел описание такой конструкции, поясните пожалуйста




Пользователь добавил сообщение 03 Июль 2017, 17:51:13:
Цитировать
При вызове флага d можно указывать пару шаблонов - будут удалены строки, в которых встретится шаблон, и те строки, которые находятся между ними

например, sed '/третий/,/пятый/d' ./file4.txt
 Но не очень похоже на вашу конструкцию .

Пользователь добавил сообщение 03 Июль 2017, 20:35:12:
/workgroup\s*=/ - найти все строки вот по - такому шаблону
{/^\tw.* = \bWORKGROUP\b/! d} - удалить все строки , кроме подвыражения '/^\tw.* = \bWORKGROUP\b/ 'заключенного в фигурные скобки
! - этот символ, символ отрицания

 Тогда конструкция будет такого вида

sed "/шаблон//d"

Я правильно все понял ?
« Последнее редактирование: 03 Июль 2017, 20:35:12 от alex-sky »

Оффлайн Azure

  • Модератор раздела
  • Старожил
  • *
  • Сообщений: 6015
  • Windows10, i3wm on Debian9, Manjaro20.0
    • Просмотр профиля
sed '/шаблон/{/замена/! d}'
Правильно так
Код: Bash
  1. sed '/шаблон1/{/шаблон2/! d}'
Действие внутри { } будет производится над строками удовлетворяющими шаблон1.
! – для чего он здесь?
! — знак инверсии/отрицания, т.е. удаляться (d) должны строки НЕ содержащие шаблон2
Таким образом удалятся все строки с workgroup, которые НЕ удовлетворяют '\tworkgroup = WORKGROUP'
Почему здесь решили использовать якорь?
Чтоб исключить например "\tworkgroup = WORKGROUP22"
В Линукс можно сделать ВСЁ что угодно, достаточно знать КАК !

 

Страница сгенерирована за 0.292 секунд. Запросов: 24.