redirecting in a shell script

2019-09-02 20:59发布

I'm trying to write a script to swap out text in a file:

sed s/foo/bar/g myFile.txt > myFile.txt.updated
mv myFile.txt.updated myFile.txt

I evoke the sed program, which swaps out text in myFile.txt and redirects the changed lines of text to a second file. mv then moves .updated txt file to myFile.txt, overwriting it. That command works in the shell.

I wrote:

#!/bin/sh
#First, I set up some descriptive variables for the arguments
initialString="$1"
shift
desiredChange="$1"
shift
document="$1"
#Then, I evoke sed on these (more readable) parameters
updatedDocument=`sed s/$initialString/$desiredChange/g $document`
#I want to make sure that was done properly
echo updated document is $updatedDocument
#then I move the output in to the new text document
mv $updatedDocument $document

I get the error:

mv: target `myFile.txt' is not a directory

I understand that it thinks my new file's name is the first word of the string that was sed's output. I don't know how to correct that. I've been trying since 7am and every quotation, creating a temporary file to store the output in (disastrous results), IFS...everything so far gives me more and more unhelpful errors. I need to clear my head and I need your help. How can I fix this?

3条回答
beautiful°
2楼-- · 2019-09-02 21:12

Maybe try

echo $updatedDocument > $document
查看更多
小情绪 Triste *
3楼-- · 2019-09-02 21:22

Change

updatedDocument=`sed s/$initialString/$desiredChange/g $document`

to

updatedDocument=${document}.txt
sed s/$initialString/$desiredChange/g $document

Backticks will actually put the entire piped output of the sed command into your variable value.

An even faster way would be to not use updatedDocument or mv at all by doing an in-place sed:

sed -i s/$initialString/$desiredChange/g $document

The -i flag tells sed to do the replacement in-place. This basically means creating a temp file for the output and replacing your original file with the temp file once it is done, pretty much exactly as you are doing.

查看更多
SAY GOODBYE
4楼-- · 2019-09-02 21:31
#!/bin/sh
#First, I set up some descriptive variables for the arguments
echo "$1" | sed #translation of special regex char like . * \ / ? | read -r initialString
echo "$2" | sed 's|[\&/]|\\&|g' | read -r desiredChange
document="$3"

#Then, I evoke sed 
sed "s/${initialString}/${desiredChange}/g" ${document} | tee ${document}

don't forget that initialString and desiredChange are pattern interpreted as regex, so a trnaslation is certainly needed sed #translation of special regex char like . * \ / ? is to replace by the correct sed (discuss on several post on the site)

查看更多
登录 后发表回答