Unix 在shell脚本中重定向

Unix 在shell脚本中重定向,unix,replace,sed,sh,Unix,Replace,Sed,Sh,我正在尝试编写一个脚本来交换文件中的文本: sed s/foo/bar/g myFile.txt>myFile.txt.updated mv myFile.txt.updated myFile.txt 我调用sed程序,它交换myFile.txt中的文本,并将更改的文本行重定向到第二个文件。mv然后将.updated txt文件移动到myFile.txt,覆盖它。该命令在shell中工作 我写道: #!/bin/sh #First, I set up some descriptive varia

我正在尝试编写一个脚本来交换文件中的文本:

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

我调用sed程序,它交换myFile.txt中的文本,并将更改的文本行重定向到第二个文件。mv然后将.updated txt文件移动到myFile.txt,覆盖它。该命令在shell中工作

我写道:

#!/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
我得到一个错误:

mv:target`myFile.txt'不是目录

我知道它认为我的新文件名是sed输出的字符串的第一个字。我不知道该怎么纠正。从早上7点开始,我一直在尝试每一个引用,创建一个临时文件来存储输出(灾难性的结果),如果……到目前为止,所有的一切都给我带来越来越多的无用错误。我需要清醒一下,我需要你的帮助。我怎样才能解决这个问题?

也许可以试试

echo $updatedDocument > $document
改变

Backticks实际上会将sed命令的整个管道输出放入变量值中

一种更快的方法是,通过执行就地
sed
,根本不使用
updatedDocument
mv

sed -i s/$initialString/$desiredChange/g $document
i标志告诉sed就地进行替换。这基本上意味着为输出创建一个临时文件,并在完成后将原始文件替换为临时文件,这与您正在做的几乎完全相同

#!/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}
不要忘记initialString和desiredChange是被解释为regex的模式,所以确实需要一个trnasalation
sed#特殊正则字符的翻译,如。*\/
将被正确的sed替换(在网站上的几篇文章中讨论)

似乎您正在尝试运行您编写的脚本,其中包含一些通配符模式作为输入文件。试着用一个文件作为文件名运行,看看会发生什么。我敢打赌,当你用双引号引用所有变量时,你会很好。如果您发布脚本的所有输入/参数和输出,这将非常有用。@user2719058,嗯,不,您不好。我相信您不是指
echo
,而是指
cat
。正确的?实际上,最好使用
cat$updatedocument>$document
构造,因为这样可以保持文件的所有权和权限不变,前提是您对此文件具有读/写访问权限。不,sed命令的输出现在位于变量updatedocument中。updatedDocument包含文件的内容,而不是文件名。lol多么圆滑的解决方案!即使使用backticks,它也会像一个符咒一样工作,当然,因为它将字符串存储在变量中,但echo的输出将成为字符串,并且由于它只是“程序输出”,重定向操作符可以很好地处理.txt文件。请稍等,我正在修补它,非常感谢!(emacs在这台服务器上运行得很慢,等一下)天哪,这太有帮助了。用最快的方法来做!我有“冗余”错误?这样做很长一段时间,就像:正如你所做的那样:mv不能stat`myFile.txt.txt':没有这样的文件或目录。在我删除后面的.txt:mv:myFile.txt和myFile.txt之后,它们是同一个文件。我今晚要学习,尝试一些东西,弄清楚这是怎么搞砸的。这是做这件事的乐趣所在,多亏了你,我才有幸:)如果你喜欢我的解决方案,你可以投票表决或者选择它作为答案。谢谢你,你当然是对的。我希望你能链接到这些讨论中的一些,我整天都在努力搜索它们,这个网站很大,总共使用了大约50个关键词!(尝试像input sed unix等搜索。您永远不会得到想要的结果)
sed -i s/$initialString/$desiredChange/g $document
#!/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}