简体   繁体   English

在bash脚本中循环目录并处理文件

[英]Loop over directories and act on files in bash script

I have a script, /home/user/me/my_script.sh that is supposed to loop over multiple directories and process files. 我有一个脚本/home/user/me/my_script.sh,该脚本应该遍历多个目录并处理文件。 My current working directory is /home/user/me. 我当前的工作目录是/ home / user / me。 A call to ls -R yields: 调用ls -R将产生:

./projects: ./项目:

dir1 dir2 dir3 dir1 dir2 dir3

./projects/dir1: ./projects/dir1:

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

./projects/dir2: ./projects/dir2:

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

./projects/dir3: ./projects/dir3:

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

I have this script: 我有这个脚本:

#! /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

This is how it is run (from cwd /home/user/me) and the result: 这是它的运行方式(来自cwd / home / user / me)和结果:

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

This is not the expected output.The expected output is: 这不是预期的输出。预期的输出是:

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$

What should happen is the script should go into the first directory, find the *.ntf file and pass it to tool.sh. 应该发生的是,脚本应该进入第一个目录,找到* .ntf文件并将其传递给tool.sh。 At that point I would start seeing output from that tool. 到那时,我将开始看到该工具的输出。 I have run the tool on a single file: 我已经在单个文件上运行了该工具:

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$

I have tried syntax found here: How to loop over directories in Linux? 我尝试过在这里找到语法: 如何在Linux中循环目录? and here: Looping over directories in Bash 和这里: 循环在Bash中的目录

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

Result: 结果:

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

And: 和:

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

Result: 结果:

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

I'm not sure how many other iterations of wildcard and slash I can come up with. 我不确定我还能提出多少其他通配符和斜杠迭代。 What is the correct syntax? 正确的语法是什么?

First, you should remove flag -f in your shebang, because it utterly means: 首先,应该在shebang中删除标志-f ,因为这完全意味着:

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

Second, there are some typical bug patterns: spaces missing around variables (write "$dir" to cope with directory names containing spaces), there is a spurious $ in your for line (write for dir in "$1"* ) instead, the set line is incorrect ( set is a shell builtin only used to change the configuration of the shell, eg, set -x ), according to your answer to @ghoti's question it seems that the $cmd line is unnecessary. 其次,有一些典型的错误模式:变量周围缺少空格(写"$dir"来处理包含空格的目录名), for行中有一个虚假的$for dir in "$1"*for dir in "$1"* ), set行不正确( set是仅用于更改shell配置的内置shell,例如set -x ),根据您对@ghoti问题的回答,似乎$cmd行是不必要的。 Also, the backquotes syntax is deprecated and could have been replaced with cmd=$(/home/tools/tool.sh -i "$dir"/*.ntf -flag1 -flag2 -flag3 opt3) . 而且,不赞成使用反引号语法,并可以将其替换为cmd=$(/home/tools/tool.sh -i "$dir"/*.ntf -flag1 -flag2 -flag3 opt3)

This would lead to the following script: 这将导致以下脚本:

#!/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

As an aside, I would recommend to always run the ShellCheck static analyzer on your Bash scripts, in order to detect typical bugs and have feedback wrt good practices. 顺便说一句 ,我建议始终在Bash脚本上运行ShellCheck静态分析器,以检测典型的错误并获得良好实践的反馈。 If you have a Linux distribution, it should be installable with your standard package manager . 如果您有Linux发行版,则应使用标准软件包管理器进行安装。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM