我明白这段代码是针对bash
shell 的
for f in $file.docked.[0-9][0-9][0-9]
do
mv $f $f.pdb
done
这段代码是针对tcsh
shell 的
foreach f ( file.docked.[0-9][0-9][0-9] )
mv $f $f.pdb
end
这是我在阅读参考文献后明白的。作为一名学习者,我认为这两个代码都可以在bash
.有没有一种方法可以在不完全了解不同 shell 的情况下找出特定代码将在哪个 shell 中运行。扩展是否有一种方法可以使代码在所有 shell 上运行,而与编写它的 Linux shell 类型无关?
答案1
for f in $file.docked.[0-9][0-9][0-9]
do
mv $f $f.pdb
done
csh
在、tcsh
和 Bourne 系列的所有 shell(ash、bash、zsh、ksh、zsh、mksh、yash...)中是语法上有效的代码,但zsh
它最有可能做一些有用的事情。
如果该代码的目的是向当前目录中以shell 变量的内容开头并以 3 个 ASCII 十进制数字结尾的.pdb
文件名添加后缀,则在 中,您需要:$file
.docked.
bash
shopt -s failglob
for f in "$file".docked.[0123456789][0123456789][0123456789]
do
mv -- "$f" "$f.pdb"
done
(--
无论外壳如何,都需要)如bash
- 就像在 Korn shell 中一样,您需要引用参数扩展,否则它们会经历 split+glob
[0-9]
通常匹配比 0123456789 更多的字符,其列表因区域设置和系统而异。您只需要[0123456789]
匹配bash
0123456789(不,最新版本的选项globasciiranges
没有帮助)。- 当它们不匹配时,glob 不会展开,因此如果没有匹配的文件,您将在循环中获得
$f
包含的一次传递。 (获得与 csh 或 zsh 类似的行为)或(从 复制的选项)解决该问题。contents-of-file-variable.docked.[0-9][0-9][0-9]
failglob
nullglob
zsh
foreach f ( file.docked.[0-9][0-9][0-9] )
mv $f $f.pdb
end
看起来确实像csh
语法,但这又是zsh
语法。应该(t)csh
是:
foreach f ( file.docked.[0-9][0-9][0-9] )
mv -- $f:q $f:q.pdb
end
(尽管在该特定情况下,:q
与其他示例相反,s 并不是严格必需的,但保证文件名不包含 SPC、TAB、LF 或通配符)。
编写有效的代码并且用完全不同的语言做同样的事情是非常棘手的。一般称为多语言编码。这Code Golf stackex姐妹网站有一个专门的部分。但这不是您通常想做的事情。
看这个网站上的这个例子作为实现这一目标所需的长度的示例。