sed命令不';不能在shell脚本中工作

sed命令不';不能在shell脚本中工作,shell,sed,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 t

我有一个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命令的部分。

您运行的是什么命令?如果没有与文件glob匹配的内容,那么它将实际插入未展开的字符串

例如,尝试以下方法:

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

因此,您的sed脚本正在爆炸,因为它接收的文件名不存在,这意味着它将像没有指定文件参数一样工作(即stdin)。

您正在运行什么命令?如果没有与文件glob匹配的内容,那么它将实际插入未展开的字符串

例如,尝试以下方法:

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

因此,您的sed脚本正在爆炸,因为它接收的文件名不存在,这意味着它将像没有指定文件参数一样工作(即stdin)。

我想您会发现它挂在第二个
sed
上,您没有提供要处理的文件名。换句话说,它将从终端获取其标准输入

由于
-n
阻止了图案空间的默认打印,因此无法从第一个
sed
获得输出。如果试图更改实际文件而不是将更改输出到标准输出,则需要
-i
在位编辑器

如果无法使用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
head --lines=-4 oldfile.txt | tail --lines=+10 >newfile.txt
这将使用临时文件进行更改,但最后一次更改会覆盖原始文件。请记住,这会更改原始文件-如果这不是您想要的,您可以将第二个
sed
更改为输出到
${file}.tmp2
,但您必须调整后续命令以将其考虑在内

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

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
head --lines=-4 oldfile.txt | tail --lines=+10 >newfile.txt

如果您有一个
[rd]ecent
头/尾
的实现。
head
打印最后四行以外的所有行,
tail
从第十行开始打印。

我想你会发现它挂在第二个
sed
上,你没有提供文件名来处理。换句话说,它将从终端获取其标准输入

由于
-n
阻止了图案空间的默认打印,因此无法从第一个
sed
获得输出。如果试图更改实际文件而不是将更改输出到标准输出,则需要
-i
在位编辑器

如果无法使用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
head --lines=-4 oldfile.txt | tail --lines=+10 >newfile.txt
这将使用临时文件进行更改,但最后一次更改会覆盖原始文件。请记住,这会更改原始文件-如果这不是您想要的,您可以将第二个
sed
更改为输出到
${file}.tmp2
,但您必须调整后续命令以将其考虑在内

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

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
head --lines=-4 oldfile.txt | tail --lines=+10 >newfile.txt

如果您有一个
[rd]ecent
头/尾
的实现。
打印除最后四行以外的所有行,
从第十行开始打印。

将第一行更改为:

#!/bin/bash -x
这将在所有扩展发生后,在bash执行每个命令时向您显示该命令


我猜
$1/*.html
与任何文件都不匹配;因此,sed行的计算结果仅为
sed-n'1,9d'
,因此sed正试图从stdin中读取数据

将第一行更改为:

#!/bin/bash -x
这将在所有扩展发生后,在bash执行每个命令时向您显示该命令


我猜
$1/*.html
与任何文件都不匹配;因此,sed行的计算结果仅为
sed-n'1,9d'
,因此sed试图从stdin中读取如果文件不存在,我非常确定
sed
不会表现为您没有指定任何文件,相反它会痛苦地抱怨:-)如果文件不存在,我非常确定
sed
不会表现为您没有指定任何文件,相反,它痛苦地抱怨:-)不,实际上它将扩展$1 OK(可能是一个空字符串),并保持
*
不变,在这种情况下,您将得到一个错误,除非您实际上有一个文本
*.html
文件,这既不可能也不明智:-)但正如@paxdiablo所说,这里真正的根本问题几乎可以肯定是它挂在第二个sed上。不过,使用
bash-x
是一种方便的故障排除技术。不,实际上它将扩展$1 OK(可能是一个空字符串),并保持
*
不变,在这种情况下,您将得到一个错误,除非您实际拥有一个文本
*.html
文件,该文件不太可能也不明智:-),但正如@paxdiablo所说,这里真正的根本问题几乎可以肯定是它挂在第二个sed上。不过,使用
bash-x
是一种方便的故障排除技术。你是对的,当我添加文件名时,它没有挂起。但是,仍然没有从文件的开头或结尾删除任何行。不幸的是,我没有一个像样的
脑袋
。。。我指的是shell命令:)。。。但是我设法用
tail
删除了头文件,用基于ant的正则表达式剪切了结尾的行。@user766353,没有删除任何行,因为您没有用
sed
的输出替换文件
sed
通常将更改写入标准输出(而不是更改原始文件)。您通常会在输出上看到这些更改,但由于您使用了
-n
来抑制默认模式空间输出,因此它们不会出现。请参阅我的更新以获取解决方案(确保文件本身