-1

Команда expand не имеет эквивалента

sed -i <file>

expand самом деле имеет опцию -i - но это означает,

только после пропусков

Существует ли комбинация sed - expand динамический дуэт для достижения той же цели?

1 ответ1

0

Расширение утилиты GNU не предоставляет обновления «на месте», которое делает sed. Воспроизвести тот же результат довольно тривиально, хотя команда может быть немного дольше.

Невозможно проанализировать и обновить файл одновременно в произвольной файловой системе без риска повреждения, и по этой причине и другие sed фактически не делают этого, хотя и абстрагируют его от пользователя. Что делает и может воспроизвести sed - это сохранить выходные данные своей операции над объектным файлом во временном файле, а затем удалить оригинальную копию и переименовать временную в исходную.

Есть несколько способов сделать это, вот один - файл с именем orig.txt - это «расширяемый» файл:

tmp=`mktemp` && expand orig.txt > "$tmp" && mv "$tmp" orig.txt

Если вы никогда не используете аргументы за пределами имени файла для расширения, простая функция с именем «expand» может скрыть весь временный файл в исходный файл подкачки и воспроизвести поведение «sed» - эта реализация будет принимать один аргумент путь / имя файла

expand() {
  [[ "$#" -ne "1" ]] && { echo "A single argument must be provided"; exit 1; }
  tmp=`mktemp` && expand "$1" > "$tmp" && mv "$tmp" "$1"
}

С небольшой модификацией мы можем воссоздать всю расширенную функциональность, поддерживая аргументы. Есть небольшая хитрость в получении последнего аргумента, так что мы знаем имя файла объектного файла, чтобы в конечном итоге мы могли перезаписать его выводом команды expand. Последний аргумент упоминается как $ {@ -1}

expand() {
      [[ "$#" -lt "1" ]] && { echo "At least a file name argument must be provided"; exit 1; }
      # Here we capture the last argument which is the object file name
      fname="${@: -1}"
      # The upcoming call to expand passes on all arguments including the file name
      tmp=`mktemp` && expand "$@" > "$tmp" && mv "$tmp" "$fname"
    }

Я не тестировал этот код, поэтому я извиняюсь, если есть синтаксическая ошибка, которую я не уловил.

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

Если вы хотите указать, будет ли файл обновляться «на месте» или обновление будет отправлено на стандартный вывод, этот шаблон функции можно изменить, чтобы сделать это на основе дополнительного аргумента (который не передается в расширить, но меняет, как мы называем, расширить). Я не уверен, что вы ищете это, но я думаю, что у вас есть вся необходимая информация, чтобы сделать это сейчас, если вы.

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

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .