我需要在该部分末尾之前将一些文本插入到 HTML 文件中HEAD
。
我想:
sed -i "s#</head>#<style> @page { prince-shrink-to-fit: auto }
.repository-with-sidebar.with-full-navigation .repository-content
{width: 950px ! important;} </style>\n</head>#" ${1}"/"${2}"/"${i}.html
我收到错误:
sed: 1: command a expects \ followed by text
我只是没有看到我的错误。我什至尝试在样式周围使用单引号。
我想在该部分末尾之前插入的确切文本HEAD
是:
<style>
@page { prince-shrink-to-fit: auto }
.repository-with-sidebar.with-full-navigation .repository-content
{width: 950px ! important;}
</style>
编辑:这是确切的命令:
sed -i "s#</head>#<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 950px ! important;} </style>\n</head>#" ${1}"/"${2}"/"${i}.html
编辑2:为了尝试并确保我正确地格式化了命令,我也在尝试这样做:
strToInsert='<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 950px ! important;} </style>'
sed -i "s#</head>#$strToInsert\n</head>#" ${1}"/"${2}"/"${i}.html
这让我意识到我插入的文本可能有问题。
答案1
In-placesed
过程中需要制作备份文件。这-i
Apple 上的选项sed
需要扩展参数(对于它创建的备份文件)并使用下一个参数。这意味着您告诉它您希望它创建一个扩展名为“ #s</head>#...
”的备份文件。
该错误意味着它认为您指的是a
挂起命令。我猜测 的值$1
以 开头a
。因为-i
ate 前面的参数sed
认为这是要运行的脚本,而不是要更改的文件的路径,因此您会收到相应的错误。这正是您在 Applesed
和无效a
命令时会遇到的错误:
$ sed a sed: 1: "a": command a expects \ followed by text
-i
在命令中提供扩展参数sed
:
sed -i.bak "s#</head>#<style> @page { prince-shrink-to-fit: auto } .repository-with-sidebar.with-full-navigation .repository-content {width: 50px ! important;} </style>\n</head>#" "${1}/${2}/${i}.html"
并且事情会起作用(尽管请注意这\n
不是换行符转义)。如果使用单引号,甚至可以去掉“”中的空格!important
。
sed
上面的代码也适用于 GNU ,但请注意-i
不是 POSIX 选项并且一般不便于携带。
通常建议无论如何都不要使用就地修改,并自己明确地处理文件副本。不过,这取决于你。
您应该引用变量扩展${1}
等。仅引用斜杠是没有意义的,因为它们始终是文字。
答案2
我很抱歉,但读了你的声明我想在 HEAD 部分末尾插入的确切文本是......让我最初相信我们正在讨论将文本附加到文件部分而不是之前插入 - 所以我首先写了这个答案。在重新阅读问题并更仔细地研究您的示例sed
命令之后 - 我想我明白这实际上是在匹配之前插入文本。所以这个答案现在也在这里 - 您将在下面找到执行任一操作的说明。
要安全地将任意字符串i
插入或附加到行的头部/尾部,您有几个选项,每个选项都比上一个更复杂。a
sed
第一个也是最简单的一个是r
ead 命令。它需要零转义。例如,如果您要附加的字符串位于文件中,./append
您可以执行以下操作:
sed '\|</head>|r ./append' <infile >outfile
或者插入它先在匹配的过程中,您可以在打印之前将其匹配一个周期,并带有一点前瞻功能,例如:
sed -e '$!N;\|\n</head>|r ./insert' -e 'P;D' <infile >outfile
但r
ead 被指定写入标准输出 - 我不确定这将如何与-i
nplace 选项一起工作(无论如何,在我看来,这主要是一个丑陋的黑客行为)。我认为它sed
应该做与p
rint 相同的事情,并将 stdout 重定向到其命名的-i
nplace 编辑文件。
另一种选择是使用a
pend 命令 - for追加那是。为了安全地做到这一点,你只需要转义\n
行和反斜杠。你可以这样做:
printf %s\\n "$str_to_append" |
sed 's|\\|&&|g;$!s|$|\\|;1i\
\\|</head>|a\\' |
sed -f - infile >outfile
a
不过, pend 的行为被指定为r
ead 的行为,因此我再次不确定它在-i
n-place hack 中的行为如何。
如果您将a\\
上面替换为 w/ ,i\\
它将把i
文本插入到标准输出(或命名为-i
nplace edit-file - 如果这适用于您的实现) 前模式空间被写出。
如果你喜欢额外的工作,(或者,在我能想到的唯一实际用途中,您按特定顺序在每行安排多个r
eads/ pends)a
它也可以用于插入,就像我r
之前使用 ead 所做的那样:
printf %s\\n "$str_to_append" |
sed 's|\\|&&|g;$!s|$|\\|;1i\
\\|\\n</head>|a\\' |
sed -e '$!N' -f - -e 'P;D' infile >outfile
我提供的最后一个几乎是相同的,除了你还必须逃脱&
并分隔符 (通常是/
)。它可以这样工作:
printf %s\\n "$str_to_append" |
sed 's|[\/&]|\\&|g
$!s|$|\\|;$s|$|/|
1i\
/<\\/head>/s/^/\\' |
sed -f - infile >outfile
这将影响插入 -如果您希望以这种方式附加字符串,您只需将 a^
与 a交换即可。$
-i
我相当有信心无论您是否添加该选项都会起作用。
-i
最后一点,您也可以这样做,而不是使用:
sed '$d;\|</head>|r ./append' <<IN >infile
$( cat <infile; echo .)
IN
...或者,对于插入:
sed -e '$d;N;\|\n</head>|r ./insert' -e 'P;D' <<IN >infile
$( cat <infile; echo .)
IN
...这将得到你的内菲莱就地编辑,没有任何可能-i
影响的意外权限问题。