![如何编写迭代输入值的脚本?](https://linux22.com/image/128654/%E5%A6%82%E4%BD%95%E7%BC%96%E5%86%99%E8%BF%AD%E4%BB%A3%E8%BE%93%E5%85%A5%E5%80%BC%E7%9A%84%E8%84%9A%E6%9C%AC%EF%BC%9F%20.png)
我正在尝试编写一个脚本,该脚本迭代未指定数量的输入值并对每个输入值执行相同的操作。像这样的文件~/bin/trash
:
#!/usr/bin/env bash
for f in "$@"
do
mv f ~/trashcan
done
我打算像这样使用
$touch 2.txt 3.txt 4.txt # create demo files
$trash *.txt
如前所述,在 Git Bash(在 Windows 上)上运行此程序时,出现以下错误:
bash: syntax error near unexpected token `2.txt'
答案1
尝试 :
#!/usr/bin/env bash
for f; do
mv "$f" ~/trashcan
done
- '印记
$
是强制性的称呼已声明的变量 ($f
) for f in "$@"
这里不需要
答案2
在您的代码中,您忘记了循环体前面$
的。f
这也应该正确引用,以"$f"
支持带有空格等的文件名。不过,我不确定这是导致错误消息的原因(并且我在代码中没有看到任何会导致出现该错误的内容)。我期望的错误是No such file or directory
在尝试移动不存在的f
.
对于像这样的小实用程序,您可以将其转换为文件中的 shell 函数~/.bashrc
:
trash () {
local trashcan="$HOME/trashcan"
mkdir -p "$trashcan"
mv -f -v "$@" "$trashcan"
}
此功能可确保在将内容移入垃圾文件夹之前确实存在。它还将详细地执行移动,显示所移动的事物的名称。
无需在此处进行迭代,因为"$@"
将正确扩展为命令行上为函数指定的名称。
我认为想要实际迭代名称的唯一原因是,如果您想确保在执行移动之前不存在目标mv
(以便垃圾箱中的内容不会被新项目覆盖)。使用mv
GNU coreutils,您可以使用类似的方法自动完成此操作
mv -f -v --backup=numbered "$@" "$trashcan"
对于非 GNU,mv
您可能需要该循环(这将替换mv
上面 shell 函数中的 ):
local trash_ext="$RANDOM"
for name; do
while [ -e "$trashcan/${name##*/}.$trash_ext" ]; do
trash_ext="$RANDOM"
done
mv -f -v "$name" "$trashcan/${name##*/}.$trash_ext"
done
这只是通过在文件名后添加随机数来创建唯一名称的一种快速而肮脏的方法。该${name##*/}
事物将扩展为 的基本名称(路径名的文件名部分)$name
并且可以被替换为$( basename "$name" )
.