sed command doesn't work in shell script
I have a shell script that looks like the following:
#!/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
but the script hangs on the fi开发者_如何学Pythonrst sed command and I have to force exit. I'm wondering if there's anything wrong about the way I've set this up?
If I remove the first two sed commands, I can run the other parts of the script, including that final one with a sed command in it.
I think you'll find it's hanging on the second sed
, where you don't provide a file name to work on. In other words, it will take its standard input from the terminal.
You won't get output from the first sed
since -n
prevents the default printing of the pattern space. If you're trying to change the actual file rather than output the changes to standard output, you need the -i
inplace editor.
If you can't use the inplace option, you'll have to do something like:
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
This uses a temporary file for making the changes except for the last change, which overwrites the original file. Keep in mind that this changes the original - if that's not what you want, you can change the second sed
to output to ${file}.tmp2
but you'll have to adjust your subsequent commands to take that into account.
If you really want to delete the first nine and last four lines of a file, you can also use something like:
head --lines=-4 oldfile.txt | tail --lines=+10 >newfile.txt
provided you have a [rd]ecent
implementation of head/tail
. The head
prints all but the last four lines and the tail
starts printing at line ten.
What command are you running? If nothing matches the file glob, then it will physically insert the unexpanded string there.
For example, try this:
$ for i in foo/*.bar; do echo $i; done
foo/*.bar
So your sed script is bombing out because the file name it is receiving doesn't exist, which means it will act as if no file argument was specified (ie stdin).
Change the first line to:
#!/bin/bash -x
This will show you each command as bash executes it, after all expansions have taken place.
My guess is that $1/*.html
isn't matching any files; hence the sed line evaluates to just sed -n '1,9d'
and so sed is trying to read from stdin
精彩评论