如何在多个子目录中按数字顺序执行同一组命令?

如何在多个子目录中按数字顺序执行同一组命令?

在我的parent_directory 中,我有标记为E-11_G 和E-10_G 的子目录。在每个子目录中,我都有更多标记为 E-2_U、E-1_U 和 E0_U 的子目录。在每个文件夹中,我对这些文件执行命令:ander、ander.band、ander.data、ander.in 和 ander.log。

这是更好的图片:

                               parent_directory
                               E-11_G/ E-10_G/ 
                          E-2_U/ E-1_U/ E0_U/ 
            ander  ander.band  ander.data  ander.in  ander.log

我想写一个更有效的版本:

#!/bin/bash

cd parent_directory/E-11_G/E-2_U/; 
ls -l ander ander.band ander.data;
cat ander.in;
cat ander.log;
pwd;
cd ../E-1_U;
ls -l ander ander.band ander.data;
cat ander.in;
cat ander.log;
pwd;
cd ../E0_U;
ls -l ander ander.band ander.data;
cat ander.in;
cat ander.log;
pwd;
cd ../../E-10_G/E-2_U/;
ls -l ander ander.band ander.data;
cat ander.in;
cat ander.log;
pwd;
cd ../E-1_U;
ls -l ander ander.band ander.data;
cat ander.in;
cat ander.log;
pwd;
cd ../E0_U;
ls -l ander ander.band ander.data;
cat ander.in;
cat ander.log;
pwd;

我已经能够按原样成功运行这个脚本,但是,我确实需要一种更简单、更有效的编写方法,因为我实际上正在使用比我提供的更多的目录。我这样做的原因是因为我需要为每个子目录保留每个“ander”文件的某些记录。我基本上计划运行此脚本,并使用 shell > 将文本导出为文本文件,将终端窗口上显示的所有内容导出到文本文件中。这就是为什么我希望每个目录的记录按数字顺序排列。

如何使我的脚本更加高效?这就是我的目标:

#!/bin/bash

cd parent_directory/;

do i= -11, -10 
   do j= -2, 0
      cd  E-i_G/E-j_U/;
      ls -l ander ander.band ander.data;
      cat ander.in;
      cat ander.log;
      pwd;
   end
end

我知道这几乎是用 Fortran 编写的,但是 bash 脚本中有与此等效或相似的东西吗?我一直在尝试使用“for 循环”,但我似乎无法以一种能够给我与第一个脚本相同的结果的方式编写它们。

答案1

cd parent_directory/

for i in {-11..-10}
do
   for j in -2 0
   do
      (
      cd  "E${i}_G/E${j}_U/"
      ls -l ander ander.band ander.data
      cat ander.in
      cat ander.log
      pwd
      )
   done
done

笔记:

  • 您可以使用大括号表示法循环一系列数字:

    for i in {-11..-10}
    
  • 您还可以循环遍历明确的项目列表:

    for j in -2 0
    
  • 您可以更改目录,以便某些依赖于变量的地方:

    cd  "E${i}_G/E${j}_U/"
    
  • 该命令的参数cd是相对于当前目录指定的目录。在该目录中完成工作后,我们想要更改回parent_directory。有很多方法可以处理这个问题,但一种简单的方法是将cd命令和要在该目录中执行的命令放入子 shell 中,用括号表示。退出括号后,目录会自动恢复到之前的状态。

答案2

作为更通用的解决方案,您可以使用xargs.通过这种方式,您可以将操作与要操作的目录列表分离。

首先编写一个执行您需要的操作的脚本:

执行_ander.sh

#!/bin/bash

# Exit immediately on error
set -e

if [[ $# -ne 1 ]] ; then
  echo "USAGE: $0 DIRECTORY" >&2
  exit 1
fi

cd "$1"

ls -l ander ander.band ander.data
cat ander.in
cat ander.log
pwd

将脚本标记为可执行:

chmod +x perform_ander.sh

最后运行:

find -type d -name 'E*_U' | xargs -n1 ./perform_ander.sh

解释

寻找

find命令将所有匹配的文件输出到 stdout

-type d将搜索限制为目录

-name 'E*_U'将搜索限制为与 glob 匹配的目录

参数

xargs命令使用其标准输入作为参数源,并使用这些参数调用给定的命令。

-n1指定一次传递的参数不超过 1 个。

相关内容