将命令存储在文件中

将命令存储在文件中

我正在尝试将命令存储在文件中,因此我可以使用下面的代码轻松调用该文件;

./test

我需要运行这段代码;

Set n=0 ; foreach sql ( *_*.sql)
foreach? sed “s/_/-/g” $sql
foreach? @ n ++
foreach? End
echo You changed $n files

我输入以下内容;

set n = 0 > test
foreach sql ( *_*.sql) >> test

当我到达这一点时,终端中出现了一个空行,因此我盲打了以下 3 行;

foreach? sed “s/_/-/g” $sql
foreach? @ n ++
foreach? End

然后我结束:

echo 'echo You changed $n files' >> test

完成后,输出文件仅包含以下内容:

foreach? sed "s/_/-/g" $sql
foreach? @ n ++
foreach? end
echo You changed $n file

完全错过了 set 命令和 foreach 循环的开始。我在这里缺少什么?还是根本不可能?

已编辑

#!/bin/tcsh
set n=0
foreach sql ( *_*.sql )
sed "s/_/-/g" $sql
@ n ++
end
echo You changed $n files
chmod 777 test

答案1

尝试从 shell 命令行执行的操作充满了问题。你必须echo重定向每一个行,并且您必须引用任何 shell 元字符,以免它们被当前 shell 解释并且不会将其放入您正在创建的文件中。您最好使用文本编辑器来编辑test文件并直接在其中输入 shell 命令。

答案2

您的脚本中仍然存在多个问题。

首先,文本编辑器是99% 的情况下创建脚本的正确方法。使用 echo 命令手动逐行构建它是乏味的并且没有任何优势。 (另外 1% 涵盖的情况是,您所在的系统没有您熟悉的编辑器,或者有充分的理由使用程序自动生成脚本,这两种情况都不适用于您的应用程序)案件。)

第一行应该是#!/bin/tcsh -f,不是#!/bin/tcsh。告诉-f它不要获取您的启动文件(.tcshrc.cshrc.login),因此您的脚本将是独立的。缺少-f可能不会造成任何问题,但拥有它是一个很好的做法。 (注意:这不适用于shbash脚本;对于这些 shell,则-f完全意味着其他内容。)

这行:

sed "s/_/-/g" $sql

读取每个文件,将所有下划线更改为连字符 - 但输出写入 stdout,不是回到输入文件。文件本身没有改变。因为你后来这样做了:

echo You changed $n files

我认为这不符合你的计划。

就地修改文件实际上相当棘手。我会做这样的事情:

sed "s/_/-/g" $sql > $sql.tmp && mv $sql.tmp $sql

这会修改文件$sql,将修改后的版本写入临时文件。 如果成功后,它将临时文件重命名为$sql.

还有一个-i选项sed可以做类似的事情;另一种方法是:

sed -i.bak "s/_/-/g" $sql

缩进是你的朋友。foreach和行之间的所有内容都end应该缩进以显示代码的结构。 (我自己使用 4 个空格;有些人更喜欢不同数量的空格,或者使用制表符。)

最后,chmod 777 test不应该出现在test脚本本身中。您需要从命令行执行该命令,以使test脚本可执行。和777是一个坏主意;它使你的脚本可读、可执行,并且可写由系统上的每个人。代替使用chmod +x test

确保通过键入./test而不只是键入来执行脚本test。 (您的问题表明您已经这样做了。)否则,您可能会执行内置test命令而不是脚本。命名你的 script 并没有什么问题test,只要你 (a) 一致地使用./test语法来调用它,并且 (b) 你.$PATH.

如果您要编写大量脚本,则应该考虑使用shorbash而不是cshor tcsh这篇文章解释了原因。

最后(这可能是这里最重要的一课),您实际上还没有告诉我们您想要做什么。我思考您想要修改某些文件的内容,用连字符替换下划线。或者您想更改它们的名称而不是内容?不可能确定您要做什么,因为您向我们展示的只是一大块代码那行不通。向我们展示无法工作的代码并没有什么问题,但我们无法建议您如何修复它,除非您用英语告诉我们您想要完成的任务。

答案3

按照建议,使用编辑器编写 shell 脚本。

这里是对你的更正编辑版本:

您需要编写set n=0而不是n=0摆脱“命令未找到”错误消息,

foreach sql ( *_*.sql )代替foreach sql *_*.sql

end不是End.

您需要普通引号,"而不是引用 sed 的参数。

相关内容