sed命令在shell脚本中不起作用

时间:2011-07-19 03:29:00

标签: shell sed

我有一个如下所示的shell脚本:

#!/bin/bash
for file in $1/*.html; do
   echo "Working on $file ..."

   # delete headers in html files.
   sed -n '1,9d' $file

   # delete the last 4 lines of the file.
   sed -n -e :a -e '1,4!{P;N;D;};N;ba'

   # ant runs regex task on all apt files
   ant -Dtarget.file=$file

   # all .html are changed to .md
   mv $file `echo $file | sed 's/\(.*\.\)html/\1md/'` ;

done

但脚本挂在第一个sed命令上,我必须强行退出。我想知道我的设置方式是否有任何不妥之处?

如果我删除前两个sed命令,我可以运行脚本的其他部分,包括最后一个带有sed命令的部分。

3 个答案:

答案 0 :(得分:4)

我认为你会发现它挂在 second sed上,你不提供文件名来处理。换句话说,它将从终端获取其标准输入。

您将无法从第一个sed获得输出,因为-n会阻止默认打印模式空间。如果您尝试更改实际的文件而不是将更改输出到标准输出,则需要-i inplace编辑器。

如果您无法使用inplace选项,则必须执行以下操作:

sed -n '1,9d' ${file} >${file}.tmp0
sed -n -e :a -e '1,4!{P;N;D;};N;ba' ${file}.tmp0 >${file}
rm -f ${file}.tmp0

这使用临时文件进行更改,但最后一次更改除外,它会覆盖原始文件。请注意,此更改原件 - 如果这不是您想要的,您可以将第二个sed更改为输出到${file}.tmp2,但您必须调整后续版本命令将其考虑在内。

如果您确实要删除文件的前九行和后四行,您还可以使用以下内容:

head --lines=-4 oldfile.txt | tail --lines=+10 >newfile.txt

如果您[rd]ecent实施head/tailhead打印除最后四行之外的所有行,tail开始在第十行打印。

答案 1 :(得分:0)

你在运行什么命令?如果没有任何内容匹配文件glob,那么它将在那里物理插入未扩展的字符串。

例如,试试这个:

$ for i in foo/*.bar; do echo $i; done
foo/*.bar

所以你的sed脚本正在轰炸,因为它接收的文件名不存在,这意味着它将表现为没有指定文件参数(即stdin)。

答案 2 :(得分:0)

将第一行更改为:

#!/bin/bash -x

在所有扩展完成后,这将显示每个命令,因为bash执行它。

我的猜测是$1/*.html与任何文件都不匹配;因此sed行评估为sed -n '1,9d',所以sed试图从stdin读取