#shell
#оболочка
Вопрос:
Требуется много времени, чтобы добавить 4 пробела к некоторым выводам оболочки и преобразовать их в действительный код markdown. Например. При публикации вопроса или ответа здесь, в stackoverflow.
На самом деле это довольно легко сделать с sed
:
some_command | sed -e 's/^/ /'
Но я бы хотел сделать это с paste
, если возможно. Поскольку paste
в качестве входных данных используется 2 файла, все, что я придумал, это:
some_command | paste 4_space_file -
где 4_space_file
на самом деле это файл, все содержимое которого состояло из 4 пробелов.
Есть ли более аккуратный способ добиться этого с paste
без фактического файла на жестком диске?
Комментарии:
1. Что вы делаете, если ваша
4_space_file
длина отличается от длины вывода изsome_command
? Кроме того, что вы делаете с символом табуляции, которыйpaste
вставляется? (То есть: Я подвергаю сомнению предположение, встроенное в этот вопрос, чтоpaste
является подходящим инструментом для текущей работы).
Ответ №1:
Буквальные ответы с использованием вставки
Во-первых, чтобы ответить на ваш буквальный вопрос:
some_command | paste <(printf ' n') -
…выдает тот же результат, что и передача paste
имени файла с одной строкой, содержащей четыре пробела и новую строку в качестве содержимого. Однако вывод из paste
в этом случае представляет собой не четырехсимвольные отступы для каждой строки; первая строка содержит четыре пробела и табуляцию, перед последующими строками ставится только табуляция.
Если бы вы хотели сгенерировать входные данные соответствующей длины, продолжая использовать paste
, то в итоге получили бы что-то более уродливое. Скажем (с bash 4.0 или новее):
ls | {
mapfile -t lines # read output from ls into an array
# our answer, here, is to move to three spaces in the input, and use paste -d' ' to
# ...add a fourth space during processing.
paste -d' '
<(yes ' ' | head -n "${#lines[@]}")
<(printf '%sn' "${lines[@]}")
}
<()
это синтаксис подстановки процесса, который расширяется до имени файла, которое при чтении из которого выдает вывод из содержащегося кода.
Лучшие ответы
Для собственного подхода bash вы также можете рассмотреть возможность определения функции:
ident4() { while IFS= read -r line; do printf ' %sn' "$line"; done; }
…для последующего использования:
some_command | indent4
В отличие от paste
, это фактически вставляет ровно четыре пробела (без промежуточной табуляции) в каждую строку для точного количества строк в вашем вводе (нет необходимости синтезировать правильную длину).
Также рассмотрите awk
:
awk '{ print " " $0; }'