我正在尝试将命令存储在文件中,因此我可以使用下面的代码轻松调用该文件;
./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
可能不会造成任何问题,但拥有它是一个很好的做法。 (注意:这不适用于sh
或bash
脚本;对于这些 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
.
如果您要编写大量脚本,则应该考虑使用sh
orbash
而不是csh
or tcsh
。 这篇文章解释了原因。
最后(这可能是这里最重要的一课),您实际上还没有告诉我们您想要做什么。我思考您想要修改某些文件的内容,用连字符替换下划线。或者您想更改它们的名称而不是内容?不可能确定您要做什么,因为您向我们展示的只是一大块代码那行不通。向我们展示无法工作的代码并没有什么问题,但我们无法建议您如何修复它,除非您用英语告诉我们您想要完成的任务。
答案3
按照建议,使用编辑器编写 shell 脚本。
这里是对你的更正编辑版本:
您需要编写set n=0
而不是n=0
摆脱“命令未找到”错误消息,
foreach sql ( *_*.sql )
代替foreach sql *_*.sql
而end
不是End
.
您需要普通引号,"
而不是“
引用 sed 的参数。