循环通过&007的结果是bash shell脚本
有没有人有一个模板shell脚本,可以用ls
来做一些事情,用ls
来做一个目录名的列表,然后循环通过每一个目录名来做一些事情?
我打算做ls -1d */
来得到目录名的列表。
有没有人有一个模板shell脚本,可以用ls
来做一些事情,用ls
来做一个目录名的列表,然后循环通过每一个目录名来做一些事情?
我打算做ls -1d */
来得到目录名的列表。
**编辑了一下,不使用ls,如 @shawn-j-goff 和其他人建议的那样,在 glob 的地方使用 ls。
在for..do..done
循环中,你只需要用元符号前缀来引用循环变量(在上面的例子中就是*
)。你可以对它进行*.txt
,或者对它做其他任何你想做的事情。
例如,将当前目录中的所有$(cat filelist.txt)
文件重命名为do
:
for f in *; do
echo "File -> $f"
done
或者,如果你使用Bash,你可以使用Bash参数扩展,而不是产生一个子hell:
for x in *.xml; do
t=$(echo $x | sed 's/\.xml$/.txt/');
mv $x $t && echo "moved $x -> $t"
done
使用ls
的输出来获取文件名是个坏主意。它可能会导致脚本出现故障,甚至是危险的脚本。这是因为除了/
和null
character之外,文件名可以包含任何字符,而ls
不使用这两个字符作为分隔符,所以如果文件名中有空格或换行,你会得到意想不到的结果。在这里,我用简单的echo
来演示如何使用文件名做一些事情,不过你可以使用任何东西。
for dir in */; do
echo "$dir"
done
find . -type d -exec echo '{}' \;
shell将*/
扩展成独立的参数,由for
循环读取;即使文件名中存在空格、换行或其他奇怪的字符,for
也会把每个完整的名字看成一个原子单位;它不会以任何方式解析列表。如果你的shell没有这些功能,或者你想确保你的脚本能在各种系统上工作,那么下一个选择是使用bash
。每找到一个文件,它都会这样做一次。
globstar
参数的语法看起来有点滑稽,find
把find
之后的第一个参数作为要运行的程序,之后的每一个参数都作为一个参数传递给这个程序。有两个特殊的参数是echo
需要看到的。第一个是-exec
,这个参数会被替换成find
前面部分产生的文件名。第二个是-exec
,它让-exec
知道这是要传递给程序的参数列表的结束;{}
需要这个,因为你可以继续使用更多的参数,这些参数是为find
准备的,而不是为执行程序准备的。之所以要使用;
,是因为shell也会特别对待find
–它代表了一个命令的结束,所以我们需要将其转义,这样shell就会将其作为参数给find
,而不是将其作为自己的参数;另一种让shell不特别对待它的方法是将其放在引号中:find
和[使用
ls的输出来获取文件名是个坏主意]&003。它可能会导致脚本出现故障,甚至是危险的脚本。这是因为除了
/和
nullcharacter之外,文件名可以包含任何字符,而
ls不使用这两个字符作为分隔符,所以如果文件名中有空格或换行,你会得到意想不到的结果。在这里,我用简单的
echo`来演示如何使用文件名做一些事情,不过你可以使用任何东西。
for dir in */; do
echo "$dir"
done
find . -type d -exec echo '{}' \;
shell将*/
扩展成独立的参数,由for
循环读取;即使文件名中存在空格、换行或其他奇怪的字符,for
也会把每个完整的名字看成一个原子单位;它不会以任何方式解析列表。如果你的shell没有这些功能,或者你想确保你的脚本能在各种系统上工作,那么下一个选择是使用bash
。每找到一个文件,它都会这样做一次。
globstar
参数的语法看起来有点滑稽,find
把find
之后的第一个参数作为要运行的程序,之后的每一个参数都作为一个参数传递给这个程序。有两个特殊的参数是echo
需要看到的。第一个是-exec
,这个参数会被替换成find
前面部分产生的文件名。第二个是-exec
,它让-exec
知道这是要传递给程序的参数列表的结束;{}
需要这个,因为你可以继续使用更多的参数,这些参数是为find
准备的,而不是为执行程序准备的。之所以要使用;
,是因为shell也会特别对待find
–它代表了一个命令的结束,所以我们需要将其转义,这样shell就会将其作为参数给find
,而不是将其作为自己的参数;另一种让shell不特别对待它的方法是将其放在引号中:find
和一样,在这个目的上也是一样的。
如果你已经安装了 GNU Parallel http://www.gnu.org/software/parallel/ ,你可以这样做:
ls | parallel echo {} is in this dir
要将所有的 .txt 重命名为 .xml:
ls *.txt | parallel mv {} {.}.xml
要了解更多信息,请观看 GNU Parallel 的介绍视频 http://www.youtube.com/watch?v=OpaiGYxkSuQ