Intereting Posts

sed на вставке OSX на определенной строке

Поэтому я некоторое время использовал «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\ :

 [1addr]a\ text 

Напишите текст на стандартный вывод, как описано ранее.

Это затрудняет запись однострочных изображений, что, вероятно, является причиной следующего расширения GNU для команд a , i и c :

В качестве расширения GNU, если между символом a и новой строки существует не строка whitespace- \ , то текст этой строки, начинающийся с первого символа без пробела после a , берется как первая строка текста блок. (Это позволяет упростить процесс написания однострочного добавления.) Это расширение также работает с командами i и c .

Таким образом, чтобы быть переносимым с вашим синтаксисом sed , вам нужно будет добавить новую строку после a\ somehow. Самый простой способ – просто вставить цитированную новую строку:

 $ sed -e 'a\ > text' 

(где $ и > – подсказки оболочки). Если вы обнаружите, что боль, bash [1] имеет синтаксис $' ' цитирования для вставки экранов в стиле C, так что просто используйте

 sed -e 'a\'$'\n''text' 

[1] и mksh (r39b +) и некоторые раковины non-bash bourne (например, / bin / sh в FreeBSD 9+)

Как описано в этом ответе , полезно использовать команды sed, такие как i и a использовать несколько -e "..." . Понятно, что каждое из этих пунктов разделяется символами новой строки. Команды i и команды трудно использовать в сценариях inline sed в противном случае (они предназначены для использования в многострочном файле сценария sed, вызванном с помощью sed -f file ... ). Похоже, вы не можете использовать неявную новую строку, введенную в конце предложения -e , чтобы отделить a\ и строку текста, который должен быть добавлен. Но вы можете использовать его для завершения строки текста, который должен быть добавлен.

В этом конкретном случае то, что вы пытаетесь сделать, на самом деле может быть выполнено с помощью одного предложения -e ... Вам просто нужно использовать команду a правильно. По стандарту POSIX за ним следует a \ , затем за ним должна следовать новая строка, затем будет вставлена ​​оставшаяся часть следующей строки (до тех пор, пока не встретится новая строка или конец предложения -e ). Таким образом, вы можете сделать:

 sed -i "" -e $'4 a\\\n'"mode '0755'" file.txt 

Perl не страдает от таких зависимых от платформы GNU и не-GNU против «проприетарных» идиосинкразий. Вы можете сделать:

 perl -ni.old -e 'print;if ($.==4) {print "mode 0755\n"}' file 

Параметр -n' option creates a loop that reads every line of the input file. Unlike its cousin -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 -i invokes in-place replacement. The argument to invokes in-place replacement. The argument to -i (viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -e (viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -e (viz. ".old") can be dropped or changed. It leaves a backup of the unmodified file. The -e сигнализирует начало скрипта.

$. обозначает номер строки, начиная с строки-1. Таким образом, командная строка считывает «файл», а когда номер строки равен 4, он печатает эту строку, за которой следует все, что вы хотите ввести.

Я бы поспешил добавить, что Perl обязан своим корням sed , AWK и C, поэтому синтаксис для простых подстановок и т. Д. Не очень крутая кривая обучения.

GNU sed, по-видимому, намного чаще используется, чем POSIX sed, на основе примеров / учебников, которые я использовал в любом случае.

Я обнаружил, что намного проще установить GNU sed на любую используемую мной машину OSX. Если вам интересно, лучший способ сделать это – установить его через Homebrew .

Вы можете либо просто $ brew install gnu-sed , либо получить все общие утилиты GNU с помощью $ brew install coreutils .

Затем, когда вы сталкиваетесь с проблемой синтаксиса с date или какой-либо другой программой, вы можете просто использовать версию GNU. В конце концов я просто решил, что было бы проще всегда использовать версии GNU и помещать их раньше, чем системные версии в моем PATH .