Сед не заменяет все вхождения шаблона

У меня есть следующая переменная LINES с форматом date;album;song;duration;singer;author;genre,

August 2013;MDNA;Falling Free;00:31:40;Madonna;Madonna;Pop
August 2013;MDNA;I don't give a;00:45:40;Madonna;Madonna;Pop
August 2013;MDNA;I'm a sinner;01:00:29;Madonna;Madonna;Pop
August 2013;MDNA;Give Me All Your Luvin';01:15:02;Madonna;Madonna;Pop

Я хочу вывести author-songИтак, я сделал этот скрипт:

echo $LINES | sed s_"^[^;]*;[^;]*;\([^;]*\);[^;]*;[^;]*;\([^;]*\)"_"\2-\1"_g

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

Madonna-Falling Free
Madonna-I don't give a
Madonna-I'm a sinner
Madonna-Give Me All Your Luvin'

Тем не менее, я получаю это:

Madonna-Falling Free;Madonna;Pop August 2013;MDNA;I don't give a;00:45:40;Madonna;Madonna;Pop August 2013;MDNA;I'm a sinner;01:00:29;Madonna;Madonna;Pop August 2013;MDNA;Give Me All Your Luvin';01:15:02;Madonna;Madonna;Pop

Зачем?

РЕДАКТИРОВАТЬ: мне нужно использовать Sed.

4 ответа

Решение

Если ты хочешь sed чтобы увидеть более одной строки ввода, вы должны заключить переменную в кавычки:

echo "$LINES" | sed ...

Обратите внимание, что я даже не собираюсь пытаться оценить правильность вашего sed сценарий; с помощью sed вот пародия, учитывая, что awk гораздо лучше подходит для этой задачи.

Когда я управляю твоим sed скрипт на ваш вход, я получаю этот вывод:

Madonna-Falling Free;Pop
Madonna-I don't give a;Pop
Madonna-I'm a sinner;Pop
Madonna-Give Me All Your Luvin';Pop

что хорошо, за исключением дополнительного ;Pop - вам просто нужно добавить .*$ до конца вашего регулярного выражения, так что вся строка заменяется.

Исходя из вашего сообщения о выводе, я предполагаю, что ваш входной файл использует соглашение о новой строке sed надеется.

В любом случае, это довольно глупая вещь, чтобы использовать sed за. Намного лучше с awk, например:

awk 'BEGIN {FS=";";OFS="-"} {print $5,$3}'

или, чуть более кратко,

awk -F\; -vOFS=- '{print $5,$3}'

Если ваш формат абсолютно постоянен, просто попробуйте ниже:

echo $line | sed 's#.*;.*;\(.*\);.*;.*;\(.*\);.*#\2-\1#'

Похоже, что sed просматривает весь образец текста одной строкой. Таким образом, он выполняет запрошенную операцию, а остальные оставляют без изменений.
Я бы сначала посмотрел на новую строку. Как вы заполняете $LINES?
Вы также должны добавить к шаблону седьмое поле в вашем входном файле (жанре), чтобы выражение действительно потребляло весь текст, который вы хотите. И, возможно, закрепить конец шаблона на $ или же \b (граница слова) или \s (пробел) или \n (новая линия).

Другие вопросы по тегам