Чтобы вставить текст в определённую строку существующего текстового файла на Mac, используйте действие оболочки в приложении «Команды»: создайте отредактированную копию, проверьте её, а затем переименуйте в Finder. В этом руководстве одна строка вставляется перед строкой 3 на временном примере.

Задача — добавить строку в небольшой локальный текстовый файл, сохранив порядок остальных строк. Вы создадите команду Finder, принимающую ровно один файл. Текст для вставки и номер строки будут заданы в скрипте, чтобы редактирование можно было легко повторять на временных копиях.

Что значит «вставить в строку 3»?

В этой статье вставка означает размещение нового текста перед существующей строкой с указанным номером. Если в исходном файле три строки, вставка Birch перед строкой 3 даст четыре строки:

Позиция Исходный файл Отредактированный файл
1 Cedar Cedar
2 Maple Maple
3 Willow Birch
4 — Willow

Строка — это запись, отделённая символом перевода строки, а не ряд, образованный визуальным переносом в редакторе. Пустые строки тоже считаются. В примере используется обычный текст UTF-8 с окончаниями строк LF и символом перевода строки после последней строки. Для этого упражнения соблюдайте эти условия; для документов с форматированием и файлов с другими кодировками или окончаниями строк потребуется иной подход.

Команда, выполняющая редактирование, — macOS sed. Её числовые адреса считают строки начиная с 1, а команда i записывает текст вставки перед указанной строкой. Обычно она выводит преобразованное содержимое в стандартный вывод. Благодаря этим задокументированным возможностям команда сможет создать отдельный файл с результатом. Руководство Apple по sed, входящее в дистрибутив

Создайте временный текстовый файл

Откройте Терминал и вставьте этот блок настройки целиком. Он создаст на Рабочем столе папку Line Insert Demo и файл из трёх строк notes.txt. Если папка с таким именем уже существует, настройка остановится; перед повторной попыткой выберите новое имя папки.

/bin/sh <<'SH'
set -e
demo_dir="$HOME/Desktop/Line Insert Demo"
/bin/mkdir "$demo_dir"
printf '%s\n' 'Cedar' 'Maple' 'Willow' > "$demo_dir/notes.txt"
printf 'Created: %s\n' "$demo_dir/notes.txt"
SH

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

В рамках этого упражнения используйте только эту временную папку. Откройте в Finder Рабочий стол и найдите Line Insert Demo; после настройки команды вы выберете файл notes.txt.

Создайте команду Finder с правильным типом входных данных

Создайте в приложении «Команды» команду с именем Insert Birch Before Line 3. Apple описывает создание команды с помощью кнопки «Добавить» на панели инструментов: нужно задать ей имя и добавить действия из боковой панели. Создание собственной команды на Mac

Настройте её следующим образом:

  1. Откройте раздел Details команды и включите Use as Quick Action, выбрав Finder.
  2. В заголовке входных данных команды измените принимаемое содержимое на Files, отключив остальные типы.
  3. Добавьте действие Run Shell Script.
  4. Для Shell выберите /bin/sh, для Input — Shortcut Input, а для Pass Input — as arguments.
  5. Замените пример скрипта в действии программой из следующего раздела целиком.

Apple описывает, как включить команды Finder и ограничить допустимые типы входных данных. Тип Files включает множество видов документов, поэтому эта настройка позволяет передавать команде файлы, но не проверяет их текстовый формат. Более узкие проверки выполняет скрипт. Запуск команды во время работы на Mac, Ограничение входных данных команды, Типы входных данных

Здесь важна цепочка передачи входных данных: Finder передаёт файл приложению «Команды», а действие оболочки передаёт его путь как аргумент, доступный в скрипте через $1. Не добавляйте перед действием оболочки действие для чтения текста: программе нужен путь к файлу, чтобы прочитать исходный файл и выбрать имя для выходного файла в той же папке.

Apple подтверждает, что приложение «Команды» для Mac поддерживает запуск скриптов оболочки прямо в редакторе. Если выполнение скриптов отключено, выберите Shortcuts > Settings, откройте Advanced и включите Allow Running Scripts. Знакомство с приложением «Команды» для macOS, Расширенные настройки приложения «Команды»

Вставьте строку и создайте отдельный результат

Полностью вставьте эту программу в действие Run Shell Script. Она требует один существующий обычный файл, вставляет Birch перед строкой 3 и записывает рядом новый файл, добавляя .inserted.txt к пути исходного файла.

#!/bin/sh
set -eu

fail() {
    printf '%s\n' "$1" >&2
    exit 1
}

[ "$#" -eq 1 ] || fail 'Select exactly one example text file.'
file=$1
line=3

case "$file" in
    /*) ;;
    *) fail 'The input must be an absolute file path.' ;;
esac

[ -f "$file" ] || fail 'The input file does not exist or is not a regular file.'
[ ! -L "$file" ] || fail 'Select the example file itself, not a symbolic link.'
[ -r "$file" ] || fail 'The input file cannot be read.'

count=$(/usr/bin/sed -n '$=' "$file") || fail 'Could not count the input lines.'
[ -n "$count" ] || fail 'The input file is empty.'
[ "$line" -le "$count" ] || fail 'The insertion line is beyond the end of the file.'

output="${file}.inserted.txt"
if [ -e "$output" ] || [ -L "$output" ]; then
    fail 'The output name already exists. Inspect or rename that result first.'
fi

if (
    set -C
    /usr/bin/sed "${line}i\\
Birch
" "$file" > "$output"
); then
    printf 'Created edited copy: %s\n' "$output"
else
    fail 'Could not finish the edited copy. Inspect any partial output before retrying.'
fi

Переводы строк внутри выражения sed намеренные. Оставьте обратную косую черту после i, следующий перевод строки и текст вставки на отдельной строке. Структура команды соответствует руководству Apple; она не полагается на сокращённую запись вставки, скопированную из другой реализации sed. Руководство sed: команды и текст вставки

Проверки в скрипте задают правила выполнения. Перед вставкой в строку с указанным номером эта строка должна существовать. Поэтому программа отклоняет пустой файл и номер строки, превышающий число строк в файле. Она также отказывается использовать уже существующее имя выходного файла, а режим оболочки noclobber обеспечивает дополнительную проверку при открытии выходного файла.

Скрипт считывает исходный файл и записывает отдельный. Если запись не удастся, исходный файл останется доступен, но может остаться неполный выходной файл. Считайте ошибку признаком незавершённой операции и проверьте выходной файл, прежде чем удалять его или повторять попытку. Запускайте только один экземпляр за раз и не меняйте исходный файл во время операции.

Результат действия — текстовое сообщение о состоянии с путём, а не файловый объект приложения «Команды». Отредактированный файл создаётся перенаправлением вывода в скрипте. Если добавить после этого действие Save File, оно сохранит результат действия, а не выполнит нужную вставку строки. Apple описывает Save File как действие для управления файлами при публикации; в документации не говорится, что оно предназначено для редактирования строк с заданными номерами. Общие сведения о действиях публикации в приложении «Команды» на Mac

Запустите команду, проверьте результат и сохраните исходное имя файла

В Finder щёлкните с зажатой клавишей Control временный файл notes.txt и выберите Quick Actions, затем Insert Birch Before Line 3. Apple описывает этот способ запуска. Если команды нет в меню, проверьте, что в её настройках включён Finder и среди допустимых входных данных есть Files. Запуск команды во время работы на Mac

После успешного запуска в демонстрационной папке будут файлы notes.txt и notes.txt.inserted.txt. Откройте второй и убедитесь, что его содержимое точно такое:

Cedar
Maple
Birch
Willow

Также можно проверить выходной файл из Терминала с помощью этой полной команды:

/bin/cat "$HOME/Desktop/Line Insert Demo/notes.txt.inserted.txt"

Чтобы сохранить отредактированное содержимое по исходному пути, закройте документы примера и выполните в Finder эти два переименования. Сначала убедитесь, что имя notes.original.txt не занято; если такой файл существует, выберите другое свободное имя для резервной копии.

  1. Выберите notes.txt, нажмите Return, переименуйте файл в notes.original.txt, затем снова нажмите Return.
  2. Выберите notes.txt.inserted.txt, нажмите Return, переименуйте файл в notes.txt, затем снова нажмите Return.
  3. Откройте файл с новым именем notes.txt и проверьте четыре строки.

Apple описывает выбор объекта и нажатие Return для переименования. Сохраните окончание .txt в обоих именах. Если Finder сообщает о совпадении имён, остановитесь и проверьте существующий объект, прежде чем выбирать свободное имя. Переименование файлов, папок и дисков на Mac

В итоге отредактированное содержимое будет находиться по пути notes.txt, а исходное — по пути notes.original.txt. В результате меняется файл, занимающий исходный путь; идентичность исходного файла не сохраняется, и нет гарантии, что его теги Finder, расширенные атрибуты и другие метаданные будут перенесены.

Измените вставку, сохранив её смысл

Для другого временного файла измените line=3, указав номер существующей строки, и замените Birch простым текстом в одну строку. Не меняйте показанный синтаксис вставки. В примере намеренно нет кавычек, знаков доллара, обратных апострофов или обратных косых черт; для произвольного текста потребуется дополнительное экранирование в оболочке и sed.

Перед редактированием скрипта воспользуйтесь этой таблицей:

Что нужно сделать Действие
Поместить текст перед первой строкой Укажите line=1 для непустого файла-примера.
Поместить текст перед другой существующей строкой Укажите line с положительным номером этой строки.
Добавить текст после последней строки Используйте отдельную операцию добавления; эта программа отклоняет несуществующий номер целевой строки.
Вставить текст в пустой файл Отдельно создайте его исходное содержимое: в пустом файле нет существующей строки, на которую можно указать.
Запустить одну и ту же команду дважды Сначала проверьте предыдущий результат. После замены исходного файла повторный запуск вставит ещё одну копию текста.

Для этой задачи на компьютере важны четыре этапа: выбранный файл, позиция вставки, готовый результат и итоговое имя файла. Когда четырёхстрочный пример будет готов, та же последовательность поможет проверить другую простую вставку, сохранив доступ к исходному тексту.

Источники