循环浏览目录并使用bash脚本处理文件

时间:2018-06-28 19:37:06

标签: bash loops for-loop

我有一个脚本/home/user/me/my_script.sh,该脚本应该遍历多个目录并处理文件。我当前的工作目录是/ home / user / me。调用ls -R会产生:

./项目:

dir1 dir2 dir3

./ projects / dir1:

image1.ntf points2.csv image1.img image1.hdr

./ projects / dir2:

image2.ntf points2.csv image2.img image2.hdr

./ projects / dir3:

image3.ntf points3.csv image3.img image3.hdr

我有这个脚本:

#! /bin/bash -f
for $dir in $1*
do
  echo $dir
  set cmd = `/home/tools/tool.sh -i $dir/*.ntf -flag1 -flag2 -flag3 opt3`
  $cmd
done

这是它的运行方式(来自cwd / home / user / me)和结果:

bash-4.1$ ./myscript.sh projects/
projects/*
bash-4.1$

这不是预期的输出。预期的输出是:

bash-4.1$ ./myscript.sh projects/
projects/dir1
[output from tool.sh]
projects/dir2
[output from tool.sh]
projects/dir3
[output from tool.sh]
bash-4.1$

应该发生的是,脚本应该进入第一个目录,找到* .ntf文件并将其传递给tool.sh。到那时,我将开始看到该工具的输出。我已经在单个文件上运行了该工具:

bash-4.1$ /home/tools/tool.sh -i /home/user/me/projects/dir1/image1.ntf -flag1 -flag2 -flag3 opt3
[expected output from tool. lengthy.]
bash-4.1$

我尝试在以下位置找到语法:How to loop over directories in Linux?和此处:Looping over directories in Bash

for $dir in /$1*/
do ...

结果:

bash-4.1$ ./myscript.sh projects/
/projects/*/

并且:

for $dir in $1/*
do ...

结果:

bash-4.1$ ./myscript.sh projects
projects/*

我不确定我还能提出多少其他通配符和斜杠迭代。正确的语法是什么?

1 个答案:

答案 0 :(得分:2)

首先,您应该在shebang中删除标记-f,因为这完全意味着:

$ man bash
[…]
        -f      Disable pathname expansion.

第二,有一些典型的错误模式:变量周围缺少空格(写"$dir"以应对包含空格的目录名),在$行中有一个虚假的for(根据您的说法,请写for dir in "$1"*),而不是set行(set是内置的shell,仅用于更改shell的配置,例如set -x)。回答@ghoti的问题,似乎不需要$cmd行。同样,不赞成使用反引号语法,并且可以将其替换为cmd=$(/home/tools/tool.sh -i "$dir"/*.ntf -flag1 -flag2 -flag3 opt3)

这将导致以下脚本:

#!/bin/bash
for dir in "$1"*
do
  [[ -d "$dir" ]] || continue  # only consider existing folders
  printf "%s=%q\n" dir "$dir"
  /home/tools/tool.sh -i "$dir"/*.ntf -flag1 -flag2 -flag3 opt3
done

顺便说一句,我建议您始终在Bash脚本上运行ShellCheck静态分析器,以检测典型的错误并获得反馈。好的做法。如果您使用的是Linux发行版,则应可安装with your standard package manager