В моем текстовом файле есть много строк, содержимое которых практически одинаково. Вот некоторые из них.
Итак, я хочу перезаписать /
на -
в каждой строке, а затем вставить -
перед строкой точно над строкой, в которой перезаписан символ /
.
Прямо сейчас я пытаюсь:
cat text | sed "///s/^/- /g;s// /\n- /g"
Входной файл:
1
00:00:00,000 --> 00:00:00,000
You are older.
2
00:00:00,000 --> 00:00:00,000
By length of a sunset.
/ Is older.
3
00:00:00,000 --> 00:00:00,000
Soona.
4
00:00:00,000 --> 00:00:00,000
Noa!
/ Noa, wait!
Ожидаемый результат:
1
00:00:00,000 --> 00:00:00,000
You are older.
2
00:00:00,000 --> 00:00:00,000
- By length of a sunset.
- Is older.
3
00:00:00,000 --> 00:00:00,000
Soona.
4
00:00:00,000 --> 00:00:00,000
- Noa!
- Noa, wait!
Я обнаружил, что с таким запросом (сделайте что-нибудь в предыдущей строке) проще перевернуть файл, сделать что-то в следующей строке, а затем снова перевернуть файл.
tac file | awk 'sub(/^//, "-") {print; getline; $1 = "- " $1)} 1' | tac
Здесь я воспользуюсь тем фактом, что функция sub()
возвращает количество сделанных замен, которое можно рассматривать как логическое значение.
С СЭД
tac file | sed '/^// { s//-/; N; s/\n/&- /; }' | tac
Это с родным sed на моем Mac. Я не помню, жаловался ли GNU sed на точку с запятой перед закрывающей скобкой.
вы можете установить инструменты GNU с помощью homebrew и попробовать gsed
Использование GNU sed
$ sed -E 'N;s|([^\n]*\n)/|- \1-|;P;D' input file
или
$ sed -Ez 's|([^\n]*\n)/|- \1-|g' input_file
оба будут выводить
1
00:00:00,000 --> 00:00:00,000
You are older.
2
00:00:00,000 --> 00:00:00,000
- By length of a sunset.
- Is older.
3
00:00:00,000 --> 00:00:00,000
Soona.
4
00:00:00,000 --> 00:00:00,000
- Noa!
- Noa, wait!
Это может сработать для вас (GNU sed):
sed -E 'N;s/^(- )?(.*\n)//- \2-/;P;D' file
Откройте окно в 2 строки по всей длине файла.
Если вторая строка начинается с косой черты, замените косую черту тире и вставьте / (замените тире, за которым следует пробел) тире, за которым следует пробел.
Н.Б. Это обслуживает 2 или более строк, следующих за линиями индекса/времени.
Если ed
доступен/приемлем.
#!/bin/sh
ed -s file.txt <<'EOF'
g|^/|-s|^|- |\
+s/^./-/
,p
Q
EOF
Или, если требуется сценарий ed
(с именем script.ed
).
g|^/|-s|^|- |\
+s/^./-/
,p
Q
Затем наведите его на соответствующий файл (с именем file.txt
).
ed -s file.txt < script.ed
,p
на w
, если вас устраивает результат и требуется редактирование на месте.Еще один вариант sed:
sed 'N; \#\n/# { s//\n-/; s/^/- / }; P;D' input_file
N
добавить следующую строку\#\n/#
для пространства шаблона, соответствующего linebreak-slash
:
s//\n-/
замените linebreak-slash
(предыдущее совпадение) на linebreak-dash
s/^/- /
замените начало пространства шаблона на dash-space
P
печатать до новой строкиD
удалить до новой строки; перезапустить с полученным пространством шаблонов
пожалуйста, обновите вопрос текстовым описанием... а) правил определения того, какие строки следует изменить и как изменить... б) проблемы с текущим кодом вместе с (неправильным) выводом, сгенерированным вашим код