Подтвердить что ты не робот

Используя sed для копирования строк и удаления символов из дубликатов

У меня есть файл, который выглядит так:

@"Afghanistan.png",
@"Albania.png",
@"Algeria.png",
@"American_Samoa.png",

Я хочу, чтобы это выглядело как

@"Afghanistan.png",
@"Afghanistan",
@"Albania.png",
@"Albania",
@"Algeria.png",
@"Algeria",
@"American_Samoa.png",
@"American_Samoa",

Я думал, что могу использовать sed для этого, но я не могу понять, как хранить что-то в буфере, а затем изменять его.

Я даже использую правильный инструмент?

Спасибо

4b9b3361

Ответ 1

Это довольно легко сделать с sed, и вам даже не нужно использовать пространство удержания (вспомогательный буфер sed). Учитывая input файл ниже:

$ cat input 
@"Afghanistan.png",
@"Albania.png",
@"Algeria.png",
@"American_Samoa.png",

вы должны использовать эту команду:

sed 's/@"\([^.]*\)\.png",/&\
@"\1",/' input 

Результат:

$ sed 's/@"\([^.]*\)\.png",/&\
@"\1",/' input 
@"Afghanistan.png",
@"Afghanistan",
@"Albania.png",
@"Albania",
@"Algeria.png",
@"Algeria",
@"American_Samoa.png",
@"American_Samoa",

Эти команды являются просто командой замены (s///). Он соответствует любому, начиная с @", за которым следуют непериодические символы ([^.]*), а затем .png",. Кроме того, он соответствует всем непериодическим символам до .png",, используя скобки группы \( и \), поэтому мы можем получить то, что соответствовало этой группе. Итак, это регулярное выражение для замены:

@"\([^.]*\)\.png",

Итак, следует за заменой части команды. Команда & просто вставляет все, что было сопоставлено @"\([^.]*\)\.png", в измененном контенте. Если бы это был единственный элемент запасной части, на выходе ничего не изменилось бы. Однако после & появляется символ новой строки, представленный обратным слэшем \, за которым следует фактическая строка новой строки, а в новой строке мы добавляем строку @", за которой следует содержимое первой группы (\1), а затем строку ",.

Это просто краткое описание команды. Надеюсь это поможет. Также обратите внимание, что вы можете использовать строку \n для представления строк в некоторых версиях sed (например, GNU sed). Это сделает более сжатую и понятную команду:

sed 's/@"\([^.]*\)\.png",/&\[email protected]"\1",/' input 

Ответ 2

Вам не нужно усложняться регулярными выражениями и строками замены: используйте команду sed p для печати строки без изменений, затем измените строку и пусть она будет напечатана неявно

sed 'p; s/\.png//'

Ответ 3

Ответ Гленна Джекмана в порядке, но он также удваивает строки, которые не соответствуют выражению.

Вместо этого он удваивает только строки, которые соответствуют выражению:

sed -n 'p; s/\.png//p'

Здесь -n означает "ничего не печатать, если явно не печатается", а p в s/\.png//p принудительно завершает печать, если замена была выполнена, но в противном случае она не заставляет

Ответ 4

Я предпочитаю это над Карлесом Салой и Гленном Джекманом:

sed '/.png/p;s/.png//'

Можно просто сказать, что это личное предпочтение.

Ответ 5

или можно объединить обе версии и применить дублирование только в строках, соответствующих требуемому шаблону

sed -e '/^@".*\.png",/{p;s/\.png//;}' input