Dan*_*ite 130 bash shell shell-script
有没有人有一个模板 shell 脚本来ls为目录名称列表做一些事情并遍历每个目录并做一些事情?
我打算做ls -1d */以获取目录名称列表。
Gen*_*mer 150
正如@shawn-j-goff 和其他人所建议的那样,编辑不使用 ls 来使用 glob 。
只需使用for..do..done循环:
for f in *; do
echo "File -> $f"
done
Run Code Online (Sandbox Code Playgroud)
您可以替换*with*.txt或任何其他返回列表(文件、目录或与此相关的任何内容)的 glob、生成列表的命令,例如$(cat filelist.txt),或者实际上用列表替换它。
在do循环中,您只需引用带有美元符号前缀的循环变量($f如上例所示)。你可以echo做任何你想做的事情。
例如,.xml将当前目录中的所有文件重命名为.txt:
for x in *.xml; do
t=$(echo $x | sed 's/\.xml$/.txt/');
mv $x $t && echo "moved $x -> $t"
done
Run Code Online (Sandbox Code Playgroud)
或者更好的是,如果您使用 Bash,您可以使用 Bash 参数扩展而不是生成子shell:
for x in *.xml; do
t=${x%.xml}.txt
mv $x $t && echo "moved $x -> $t"
done
Run Code Online (Sandbox Code Playgroud)
Sha*_*off 77
使用 的输出ls来获取文件名是一个坏主意。它可能导致出现故障甚至危险的脚本。这是因为文件名可以包含除/和字符之外的任何字符null,并且ls不使用这些字符中的任何一个作为分隔符,因此如果文件名有空格或换行符,您将得到意想不到的结果。
有两种非常好的迭代文件的方法。在这里,我只是echo用来演示如何使用文件名;不过,你可以使用任何东西。
第一个是使用 shell 的本机通配功能。
for dir in */; do
echo "$dir"
done
Run Code Online (Sandbox Code Playgroud)
shell 扩展*/为for循环读取的单独参数;即使文件名中有空格、换行符或任何其他奇怪的字符,for也会将每个完整的名称视为一个原子单位;它没有以任何方式解析列表。
如果您想递归进入子目录,那么除非您的 shell 具有一些扩展的通配符功能(例如bash's globstar。如果您的 shell 没有这些功能,或者如果您想确保您的脚本可以工作),否则这不会发生在各种系统上,下一个选项是使用find.
find . -type d -exec echo '{}' \;
Run Code Online (Sandbox Code Playgroud)
在这里,该find命令将调用echo并将文件名的参数传递给它。它为它找到的每个文件执行一次。与前面的示例一样,没有解析文件名列表;相反,文件名作为参数完全发送。
-exec参数的语法看起来有点滑稽。find在之后接受第一个参数-exec并将其视为要运行的程序,并且每个后续参数都将其作为传递给该程序的参数。有两个特殊参数-exec需要查看。第一个是{}; 这个参数被替换为前面部分find生成的文件名。第二个是;,它让我们find知道这是传递给程序的参数列表的结尾;find需要这个,因为您可以继续使用更多用于find和不用于 exec 程序的参数。的原因\是外壳也处理;特别是 - 它代表一个命令的结束,所以我们需要对它进行转义,以便 shell 将它作为参数提供给find而不是自己使用它;让外壳不特殊对待它的另一种方式是把它放在引号:';'工作只是以及\;用于这一目的。
小智 28
对于包含空格的文件,您必须确保引用变量,例如:
for i in $(ls); do echo "$i"; done;
Run Code Online (Sandbox Code Playgroud)
或者,您可以更改输入字段分隔符 (IFS) 环境变量:
IFS=$'\n';for file in $(ls); do echo $i; done
Run Code Online (Sandbox Code Playgroud)
最后,根据你在做什么,你甚至可能不需要 ls:
for i in *; do echo "$i"; done;
Run Code Online (Sandbox Code Playgroud)
如果你安装了 GNU Parallel http://www.gnu.org/software/parallel/你可以这样做:
ls | parallel echo {} is in this dir
Run Code Online (Sandbox Code Playgroud)
要将所有 .txt 重命名为 .xml:
ls *.txt | parallel mv {} {.}.xml
Run Code Online (Sandbox Code Playgroud)
观看 GNU Parallel 的介绍视频以了解更多信息:http : //www.youtube.com/watch?v=OpaiGYxkSuQ
| 归档时间: |
|
| 查看次数: |
409438 次 |
| 最近记录: |