Использование grep для удаления текста после первого или второго появления строки из четырех di git. Проблема с текстом через дефис - PullRequest
1 голос
/ 06 августа 2020

Я пытаюсь использовать grep и sed для форматирования текста, и мне нужна помощь с моим оператором grep для включения дефисов и предшествующего текста в вывод.

Примеры строк:

Merry.Ex-Mas.2014.1080p.Text.x265-JOHN
30.Rock.A.One-Time.Special.2020.1080p.Text.x265-JOHN
Creature.from.the.Black.Lagoon.REMASTERED.1954.1080p.BluRay.x265-JOHN
1984.1984.1080p.Text.x265-JOHN

желаемый результат будет:

Merry Ex-Mas 2014
30 Rock A One-Time Special 2020
Creature from the Black Lagoon 1954
1984 1984

Благодаря @ grzegorz-pudłowski У меня есть эта строка кода. (но по какой-то причине дефисы и все перед ним удаляются)

`grep -E -o '(\\w*[\\.]?)*(19|20)[0-9]{2}'`

(в AppleScript требуются дополнительные экраны)

Эти команды grep приводят к:

Mas.2014
Time.Special.2020
Creature.from.the.Black.Lagoon.1954
1984.1984

Затем я перехожу к sed, чтобы заменить точки пробелами:

 | sed 's/\\. */ /g'"


Исходный ответ от @ grzegorz-pudłowski, который был удален из stackoverflow:

В этой ситуации лучше, чем sed, должно быть grep. Я предполагаю, что у вас есть куча файлов, и вы хотите их переименовать или что-то еще. Поэтому я бы использовал что-то вроде этого:

echo "Title.Text.2012.1080p.text.text" | grep -E -o "(\w*[\.]?)*(19|20)[0-9]{2}"

Итак ... -E - это флаг «расширенного регулярного выражения». Вместо этого вы можете использовать egrep. Следующий флаг - -o, и он заставляет grep печатать только совпадающее выражение (так как вы хотите выбросить остальную часть этой строки).

Regexp прост:

  • (\w*[\.]?)* match ноль или более групп из нуля или более буквенно-цифровых символов с нулем или одной точкой в ​​конце.
  • (19|20) соответствует 19 или 20, если вы хотите соответствовать году (при условии, что 1900-2099 годы, поэтому измените эту часть, если вам нужен более широкий диапазон)
  • [0-9]{2} совпадение двух цифр от 0 до 9

После этого вы можете передать результат в mv или что-то еще. Однако если вы grep файл, просто используйте:

grep -E -o "(\w*[\.]?)*(19|20)[0-9]{2}" filename.txt

Ответы [ 4 ]

4 голосов
/ 06 августа 2020

EDIT2: В случае, если OP хочет придерживаться своего исходного решения с дополнительными шагами, попробуйте следующее.

grep -E -o "(\w+\.){1,}.*(19|20)[0-9]{2}" Input_file | sed 's/\./ /g'

РЕДАКТИРОВАТЬ: В соответствии с комментарием OP, добавляя более общее c решение.

awk '
match($0,/[0-9]{4}\.[0-9]+[a-zA-Z]+\..*/){
  val=substr($0,1,RSTART+4)
  gsub(/\./," ",val)
  print val
  val=""
}
'  Input_file

Не могли бы вы попробовать следующие, написанные и протестированные на показанных примерах в GNU sed.

sed -E 's/\.[0-9]+p\.Text\..*Text//;s/\./ /g' Input_file

2-е решение: Использование awk.

awk '
BEGIN{
  FS="."
}
match($0,/\.[0-9]+p\.Text\..*Text/){
  $1=$1
  print substr($0,1,RSTART-1)
}
' Input_file
2 голосов
/ 06 августа 2020
Выражение

A sed с использованием BRE (Basi c Regular Expressions) может быть записано как:

sed 's/[.]/ /g;s/\w\w*p\s.*$//' file

Где первая подстановка глобально заменяет каждый '.' пробелом, а затем вторая удаляет от слова, оканчивающегося на 'p', до конца строки. \w соответствует [A-Za-z0-9_], поэтому вы можете ужесточить критерии сопоставления, при необходимости отрегулировав соответствие символов перед 'p'.

Пример использования / вывода

$ sed 's/[.]/ /g;s/\w\w*p\s.*$//' file
Merry Ex-Mas 2014
30 Rock A One-Time Special 2020
1984 1984

Per-Edits для включения дополнительных строк

Включая дополнительные строки, такие как:

  • "WALL-E.2008.1080p.BluRay.x265-JOHN" и
  • "WALL-E.2008.REMASTERED.1080p.BluRay.x265-RARBG"

Для использования BRE вам потребуется:

sed 's/[.]/ /g;s/^[0-9][0-9]*[ ]\([0-9][0-9][0-9][0-9]\).*$/\1 \1/;s/[ ]\([0-9][0-9][0-9][0-9]\).*$/ \1/' file

Пример входного файла

$ cat file
Merry.Ex-Mas.2014.1080p.Text.x265.Text
30.Rock.A.One-Time.Special.2020.1080p.Text.x265.Text
1984.1984.1080p.Text.x265.Text
WALL-E.2008.1080p.BluRay.x265-JOHN
WALL-E.2008.REMASTERED.1080p.BluRay.x265-RARBG

Пример использования / Выход

$ sed 's/[.]/ /g;s/^[0-9][0-9]*[ ]\([0-9][0-9][0-9][0-9]\).*$/\1 \1/;s/[ ]\([0-9][0-9][0-9][0-9]\).*$/ \1/' file
Merry Ex-Mas 2014
30 Rock A One-Time Special 2020
1984 1984
WALL-E 2008
WALL-E 2008
1 голос
/ 06 августа 2020

Это можно решить, используя замену sed:

sed -E 's/(.*(19|20)[0-9]{2}).*/\1/; s/\./ /g' file
Merry Ex-Mas 2014
30 Rock A One-Time Special 2020
1984 1984

Подробности:

  • (.*(19|20)[0-9]{2}): Match самая длинная строка, пока мы не получим строку года и не захватим группу # 1

  • .*: сопоставить оставшуюся часть до конца

  • \1 : Вернуть 1-ю группу захвата

  • s/\./ /g: заменить каждую точку пробелом c

1 голос
/ 06 августа 2020

Вы можете использовать

sed -E 's/\.1080p\..*//g;s/\./ /g' file

См. онлайн sed демо

Подробности

  • -E - включает синтаксис POSIX ERE
  • s/\.1080p\..*//g - удаляет .1080. и весь текст до конца строки
  • s/\./ /g - заменяет точки пробелами.

Тест:

#!/bin/bash
s='Merry.Ex-Mas.2014.1080p.
30.Rock.A.One-Time.Special.2020.1080p.
1984.1984.1080p.'
sed -E 's/\.1080p\..*//g;s/\./ /g' <<< "$s"

Вывод:

Merry Ex-Mas 2014
30 Rock A One-Time Special 2020
1984 1984
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...