Удалить разрыв строки в конце текста; запуск perl-скрипта внутри Automator

Я пишу perl-скрипт, который будет запускаться внутри приложения Automator для обработки документов, которые ранее обрабатывались вручную. Мне нужно выполнять этот процесс еженедельно, всегда удаляя одни и те же ненужные данные. Это файлы rtf, преобразованные из файлов html в Mac OS X с использованием другого скрипта Automator для сохранения форматирования. Я создал новый сценарий дроплета для обработки файлов rtf для удаления ненужных ненужных данных.

Мой сценарий оболочки:

#!/bin/bash
# 
#    replace CR with CRLF
#     
/usr/bin/perl -CSDA -pi <<'EOF' - "$@"
s/dateformat//og;
s/text1//og;
s/text2//og;
s/text3//og;
s///og;

EOF

Это позаботится о 99% того, что нужно сделать. Однако окончательный файл выходит с лишним разрывом строки. Есть ли способ сделать так, чтобы замена text1, text2 и т. д. включала удаление следующего за ним разрыва строки? Мое единственное ограничение состоит в том, что это должно быть запущено в окне оболочки сценария Automator.

Входные данные выборки форматируются следующим образом:

Text1 Dateformat 
[Content1] 

Text2 Dateformat
[Content2]

Text3 Dateformat
[Content3]

Сценарий выше производит вывод:

[Content1]


[Content2]


[Content3]

Желаемый вывод должен быть отформатирован как:

[Content1]

[Content2]

[Content3]

В исходном документе после блока контента есть один разрыв строки, затем Text1 и Dateformat.

Исходный документ

После обработки Text1 и Dateformat удаляются, но, как вы можете видеть, теперь между блоками контента есть два разрыва строки.

Документ после обработки с помощью дроплета Automator выше


person podel    schedule 17.05.2020    source источник
comment
Добавьте раздел DATA с примерами строк, это поможет людям понять, что они пытаются сделать.   -  person Dragos Trif    schedule 17.05.2020
comment
@DragosTrif спасибо, я добавил образец.   -  person podel    schedule 17.05.2020
comment
Perl one liner perl -0777 -pe "s/Text\d Dateformat\s*\n//g" input_file.txt -- надеюсь, проблема была правильно понята.   -  person Polar Bear    schedule 17.05.2020
comment
@PolarBear Я попробовал это. Добавление \s*\n после s/выведения dateformat не повлияло на конечный результат. У меня все еще осталось два разрыва строки между концом Content 1 и началом Content 2. Мне интересно, является ли это проблемой редактирования текста, а не perl.   -  person podel    schedule 17.05.2020


Ответы (3)


Вы можете сопоставить и удалить пробелы как часть вашего шаблона. \R – это окончание общей строки, которое соответствует любому из окончаний строки Unicode, включая пустую новую строку или пару возврата каретки/новой строки. Кроме того, взгляните на шестнадцатеричный дамп данных, чтобы увидеть, каковы настоящие окончания строк. Окончания строк в старом Mac Classic, кажется, появляются в странных местах (но \R должно справиться с этим).

\h — горизонтальный пробел:

#!/bin/bash
#
#    replace CR with CRLF
#
/usr/bin/perl -CSDA -pi <<'EOF' - "$@"
s/dateformat\R//ig;
s/text1\h+//ig;
s/text2\h+//ig;
s/text3\h+//ig;
EOF

Обратите внимание, что я добавил флаг /i для нечувствительности к регистру, поскольку все ваши шаблоны написаны строчными буквами, а данные имеют смешанный регистр.

Я также удалил переключатель /o, который больше ничего не делает.

Если по какой-то причине вы удаляете DateFormat сам по себе, вы можете просто удалить все конечные пробелы после Textn. \s получает вертикальные и горизонтальные пробелы:

#!/bin/bash
#
#    replace CR with CRLF
#
/usr/bin/perl -CSDA -pi <<'EOF' - "$@"
s/dateformat//ig;
s/text1\s+//ig;
s/text2\s+//ig;
s/text3\s+//ig;
EOF

Если вы просто хотите пропустить эти строки, вам даже не нужно делать замену. Вы можете просто пропустить их, независимо от того, есть ли у них бит DateFormat. Здесь используется -n вместо -p, поэтому я могу контролировать, когда он выводится. Для надежности я добавил якорь начала строки \A:

#!/bin/sh
/usr/bin/perl -CSDA -ni -e 'print unless /\AText[123]\s+/i' "$@"
person brian d foy    schedule 18.05.2020
comment
Это работает для удаления текста, однако у меня все еще остаются две строки между [Content]. Я добавил изображения в исходный пост, чтобы проиллюстрировать, что происходит как с моим исходным кодом, так и с вашим обновлением. - person podel; 19.05.2020
comment
Я не получаю такой же вывод, и изображения, которые вы предоставляете, не помогают мне понять вашу проблему. Как я заметил в первом абзаце, шестнадцатеричный дамп был бы полезен. - person brian d foy; 19.05.2020
comment
Настоящие окончания строк выглядят как /n. pastebin.com/g4da4Riz - person podel; 19.05.2020
comment
а вот тот же файл после обработки pastebin.com/xm8Mr01M - person podel; 19.05.2020
comment
\n — логический символ. Mac Classic использовал \r для обозначения того же самого, поэтому я хочу увидеть исходные октеты. Ни один из этих pastebins не помогает мне (и в основном то же самое, что просто показывать мне исходный файл). - person brian d foy; 19.05.2020
comment
Извините, я действительно новичок в этом. Что я могу предоставить, что могло бы помочь? Я использовал hexdump -c -n1048 для получения данных pastebin. - person podel; 19.05.2020
comment
Оригинальный файл был бы намного лучше. - person brian d foy; 19.05.2020
comment
comment
Ни один из этих файлов не похож на данные, которые вы пытаетесь обработать. Честно говоря, я не думаю, что мы можем чем-то еще помочь вам. Сейчас лучше всего разбить процесс Automator на шаги и внимательно изучить каждый шаг. Я уверен, что решение, которое я предложил для поставленного вами вопроса, является хорошим, но я думаю, что есть что-то еще в процессе разработки, что влияет на ваш результат. Удачи! - person brian d foy; 19.05.2020
comment
файлы, которые я предоставил, от начала до конца идентичны тем, которые я обрабатываю, от экспорта в исходном формате до обработки, за исключением того факта, что они являются фиктивными файлами, созданными для защиты конфиденциальности, поэтому я не уверен, где путаница. Спасибо за вашу помощь, и, надеюсь, я смогу найти решение, которое работает. Спасибо! - person podel; 19.05.2020

Этот скрипт делает то же самое, что и один лайнер

use strict;
use warnings;
use feature 'say';

my $data = do { local $/; <DATA> };

$data =~ s/Text\d+\s+Dateformat\s*//g;
say $data;

__DATA__
Text1 Dateformat 
[Content1] 

Text2 Dateformat
[Content2]

Text3 Dateformat
[Content3]

Вывод

[Content1]

[Content2]

[Content3]

ПРИМЕЧАНИЕ. Замените <DATA> на <> для чтения из канала или файла, указанного в командной строке.

person Polar Bear    schedule 17.05.2020
comment
Это меняет программу. Исходная программа удаляла строки текста, даже если они не имели частей формата даты. - person brian d foy; 18.05.2020
comment
Поскольку я запускаю этот скрипт в окне Automator, он не позволяет мне использовать say. В остальном результат по-прежнему два разрыва строки между [Content] блоками. - person podel; 19.05.2020
comment
@podel - используйте print вместо say, используйте s/\n\n/\n/, если не видите другого. - person Polar Bear; 19.05.2020

person    schedule
comment
Помещение их в хеш означает, что вы не получите их в том порядке, в котором они были в оригинале (за исключением случайного). Вам не нужно создавать структуру данных для линейно-ориентированных задач. Кроме того, вы выводите части, которые они хотят удалить. - person brian d foy; 18.05.2020