Можно ли удалить определенный повторяющийся символ из списка с помощью регулярных выражений?

Можно ли удалить определенный повторяющийся символ из списка с помощью регулярных выражений?

У меня есть список из одного столбца, содержащий ~ 100 строк, в котором некоторые строки повторяются, и моя цель - избавиться отспецифическийдублировать строки и оставить толькоодинскопируйте, а остальные строки оставьте нетронутыми.

Выдержка из файлов, над которыми я работаю:

V(Mn9)   
V(C1,H3) 
V(Mn6)   
V(Mn6)   
V(C4,H6) 
V(Mn9)   
V(Mn9)   
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)   
V(C1,C4) 
C(Mn9)   
C(Mn6)   
C(C1)    
C(C4)    
C(Mn9)   
C(Mn6)   
V(C1,H2) 
V(Mn9)   
V(Mn6)   
V(C4,H5)

Моя цель — удалить все повторяющиеся строки, содержащие C(Xx0-9), и оставить одну из них, сохранив V(Xxx..).

Результат, к которому я стремлюсь:

V(Mn9)   
V(C1,H3) 
V(Mn6)   
V(Mn6)   
V(C4,H6) 
V(Mn9)   
V(Mn9)   
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)   
V(C1,C4) 
C(C1)    
C(C4)    
C(Mn9)   
C(Mn6)   
V(C1,H2) 
V(Mn9)   
V(Mn6)   
V(C4,H5)

Я использовал команду:

sed '0,/C(Mn9)/{/C(Mn9)/d}' inputfile.txt | sed '0,/C(Mn6)/{/C(Mn6)/d}'

и это работает, но этого недостаточно для всего файла, потому что там много C(Xx1-50), я думал использовать регулярное выражение, но я не знаю как, поэтому мне нужна ваша помощь.

решение1

$ awk '!(/^C\(..[0-9])$/ && seen[$0]++)' file
V(Mn9)
V(C1,H3)
V(Mn6)
V(Mn6)
V(C4,H6)
V(Mn9)
V(Mn9)
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)
V(C1,C4)
C(Mn9)
C(Mn6)
C(C1)
C(C4)
V(C1,H2)
V(Mn9)
V(Mn6)
V(C4,H5)

Вышеуказанное предполагает, что у вас нет пробелов до/после видимых символов в вашем примере ввода. Если они есть, то удалите их, например:

$ awk '{gsub(/^[[:space:]]+|[[:space:]]+$/,"")} !(/^C\(..[0-9])$/ && seen[$0]++)' file
V(Mn9)
V(C1,H3)
V(Mn6)
V(Mn6)
V(C4,H6)
V(Mn9)
V(Mn9)
V(C1,Mn6)
V(C4,Mn9)
V(Mn6)
V(C1,C4)
C(Mn9)
C(Mn6)
C(C1)
C(C4)
V(C1,H2)
V(Mn9)
V(Mn6)
V(C4,H5)

решение2

Предлагаю использовать sedдля сбора строк в пространстве ожидания, чтобы проверить, появлялись ли они ранее:

 sed -n 'H;G;/^\(C([^)]*)\).*\1 *\n/!P'
  • Hдобавляет текущую строку в отведенное для нее место
  • Gдобавляет пространство удержания со всеми линиями, которые мы когда-либо видели, к пространству шаблона
  • C([^)]*)является одним из таких C(…)шаблонов, ^привязывает его к началу строки и окружает \(…\), поэтому на него можно ссылаться как на \1later. Нам нужен \1 *\nшаблон as с новой строкой (после возможных пробелов), чтобы избежать сопоставления с только что добавленной строкой в ​​конце. Таким образом, весь шаблон /^\(C([^)]*)\).*\1 *\n/соответствует строке с дубликатом C(…), поэтому только если это !не совпадает,
  • Pвывести все до первой новой строки (= без добавленного пробела), в то время как вывод по умолчанию подавляется -nопцией

Обратите внимание, что в зависимости от sedверсии и размера файла это может привести к сбою, поскольку со временем все строки окажутся в памяти.

Связанный контент