Так что я некоторое время использовал «sed» в linux, но столкнулся с некоторыми трудностями при попытке использовать его в OSX, поскольку «POSIX sed» и «GNU sed» имеют так много небольших различий. В настоящее время я борюсь с тем, как вставить строку текста после определенного номера строки. (в данном случае строка 4)
На Linux я бы сделал что-то вроде этого:
sed --in-place "4 a\ mode '0755'" file.txt
Итак, на OSX я попробовал это:
sed -i "" "4 a\ mode '0755'" file.txt
Однако это продолжает давать мне сообщение «дополнительные символы после \ в конце команды». Есть идеи, что здесь не так? У меня есть опечатка? Или я не понимаю другую разницу между версиями sed?
Ответы:
Строго говоря, спецификация POSIX для
sed
требует новой строки послеa\
:Это делает написание острот немного боли, которая, вероятно , является причиной для последующего расширения GNU к
a
,i
иc
команды:Таким образом, чтобы быть переносимым с вашим
sed
синтаксисом, вам нужно будет включить новую строку послеa\
каким-либо образом. Самый простой способ - просто вставить цитируемую строку:(где
$
и>
находятся подсказки оболочки). Если вы обнаружите, что боль,bash
[1] имеет$' '
синтаксис цитирования для вставки escape-символов в стиле C, так что просто используйте[1] и mksh (r39b +) и некоторые не-bash-оболочки Борна (например, / bin / sh в FreeBSD 9+)
источник
Как описано в этом ответе , полезно использовать команды sed, такие как
i
and, иa
использовать несколько-e "..."
предложений. Каждый из этих пунктов будет пониматься как разделенный новыми строками.i
Иa
команды трудно использовать в инлайн СЭД сценарии иначе (они предназначены для использования в многострочного СЭД файл сценария вызывается с помощьюsed -f file ...
). Похоже, вы не можете использовать неявный символ новой строки, введенный в конце-e
предложения, чтобы отделитьa\
строку текста от строки, которая должна быть добавлена. Но вы можете использовать его для завершения строки текста, которая будет добавлена.В этом конкретном случае то, что вы пытаетесь сделать, может фактически быть выполнено с помощью одного
-e ...
предложения. Вам просто нужно правильно использоватьa
команду. В соответствии со стандартом POSIX, после негоa
должен следовать символ «a»\
, затем за ним должна следовать новая строка, затем будет вставлена оставшаяся часть следующей строки (до тех пор, пока не встретится новая строка или конец-e
предложения). Так что вы могли бы сделать:источник
GNU sed, кажется, гораздо чаще используется, чем POSIX sed, основываясь на примерах / руководствах, которые я использовал в любом случае.
Я обнаружил, что гораздо проще просто установить GNU sed на любую машину с OSX, которую я использую. Если вам интересно, лучший способ сделать это - установить его через Homebrew .
Вы можете либо просто
$ brew install gnu-sed
, либо получить все общие утилиты GNU с$ brew install coreutils
.Затем, когда вы столкнетесь с проблемой синтаксиса с
date
какой-либо другой программой, вы можете просто использовать версию GNU. В конце концов я просто решил, что всегда проще использовать версии GNU и ставить их раньше, чем системные версии в моемPATH
.источник
Perl не страдает от таких зависимых от платформы GNU против не-GNU против «проприетарных» идиосинкразий. Вы могли бы сделать:
-n' option creates a loop that reads every line of the input file. Unlike its cousin
-P(not used here) it doesn't automatically print every line read. The
-iinvokes in-place replacement. The argument to
-i(viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -e
сигнализирует о начале сценария.$.
Обозначает линию-номер, начиная с линии-1. Таким образом, командная строка читает «файл», и когда номер строки равен 4, она печатает эту строку, за которой следует то, что вы хотите вставить.Спешу добавить, что Perl обязан своими корнями
sed
AWK и C, поэтому синтаксис простых подстановок и т. Д. Не очень крутая кривая обучения.источник
perl -wlpi.old -e 'print "mode 0755" if $. == 5' file.txt
.-p
Переключатель хорошо работает здесь (так как мы хотим напечатать каждую строку); нам просто нужно изменить логику с «печать после строки 4» на «печать до строки 5». И-l
переключатель делает так, что «\ n» печатается автоматически с каждымprint
, так что вам не нужно печатать его самостоятельно.