2016-11-07 3 views
-1

входных данных (имена файлов):Соответствие каждому происхождению '.' За исключением последних

Word1.Word2 Word3.ext 
Word1.Word2 Word3.Word4.ext 
Word1 Word2.Word2.ext 
Word1 Word2.Word3 Word4.ext 

, где .ext варьируется в зависимости от типа файла, а слова разделяются пробелом или «»

Желаемый результат:

Word1 Word2 Word3.ext 
Word1 Word2 Word3 Word4.ext 
Word1 Word2 Word3.ext 
Word1 Word2 Word3 Word4.ext 

Я знаю, что я могу заменить каждое вхождение '':

s/\\.//

, и я знаю, что я могу получить последний. с расширением:

(.[^\\.]*)$ 

, но я не могу понять, как соединить все это вместе.

ответ

0

Вот путь, который не зависит от расширения эды регулярных выражений, только акции sed:

sed 'h;s/.*\(\.[^.]*\)/\1/;x;s/\.[^.]*$//;s/\./ /g;G;s/\n//' 

Команды разделены запятой и сделать это:

  • h копирует строки в трюм, сохраняя исходный текст в то время как мы работаем,
  • s удаляет все, кроме последней точки и расширения, и нет необходимости в знаке доллара в регулярном выражении, потому что .* является достаточно жадным, чтобы взять столько строк, сколько может,
  • x свопов этой точка-и-расширение с исходной линией, что мы сохранили в трюме,
  • s удаляет последнюю точку и расширение от исходной линии,
  • s заменяют все оставшиеся точки с пробелом (и модификатор g означает заменить все из них, а не только первого),
  • G добавляет штрих-расширение, которое мы сохраненные в трюме на Dotless линий (но разделяя их символ новой строки),
  • и s удаляет эту раздражающую новую строку.

Одно замечание о исходном сообщении: ваше регулярное выражение для периода и расширения, которые вы показываете, как

(.[^\\.]*)$ 

должна быть

\.[^.]*$ 

Вне квадратных скобок, период соответствует любому символу, поэтому, если вы хотите соответствовать периоду, вам нужно сбежать от него с помощью обратного слэша. Но внутри квадратных скобок оно соответствует только периоду. И вы можете отбросить парсеры, если не пытаетесь захватить согласованную строку.

+0

Спасибо. Это идеально для меня. Спасибо за примечание о []. – Lorccan

0

Это проще сделать это с помощью perl опережения регулярного выражения:

perl -pe 's/\.(?=.*\.[^.]*$)/ $1/g' file 

Word1 Word2 Word3.ext 
Word1 Word2 Word3.Word4.ext 
Word1 Word2 Word2.ext 
Word1 Word2 Word3 Word4.ext 

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

awk -F '.' '{$(NF-1) = $(NF-1) "." $NF; NF--} 1' file 

Word1 Word2 Word3.ext 
Word1 Word2 Word3 Word4.ext 
Word1 Word2 Word2.ext 
Word1 Word2 Word3 Word4.ext 

Если вы должны использовать sed только затем использовать:

sed ':a 
s/\.\([^.]*\.\)/ \1/g 
ta' file 

Word1 Word2 Word3.ext 
Word1 Word2 Word3 Word4.ext 
Word1 Word2 Word2.ext 
Word1 Word2 Word3 Word4.ext 
+0

Ничего себе! Это было быстро. Спасибо. Я не знаю, могу ли я вводить что-то неправильно, но я все еще получаю некоторые нечетные точки в 2-й и 4-й строках: Word1 Word2 Word3.Word4 ext и Word1 Word2.Word3 Word4.ext – Lorccan

+0

Спасибо. Я уверен, что они работают, но я действительно искал решение sed, если это возможно. (Я пытаюсь повесить часть регулярного выражения!) – Lorccan

+0

Спасибо за ответ. Я нашел, что не расширенная версия работает лучше всего для меня. – Lorccan

0

тростн ниже находит:

  • Найти.
  • ничего, кроме точек.
  • найти. снова
  • ничего, кроме точек.
  • EOL
\.([^\\.]*\.[^\\.]*)$ 

Group все, но ведущий "" Затем заменить на «$ 1»

Смежные вопросы