【问题标题】:Using a bash script to apply another script to every file in a directory like a matrix使用 bash 脚本将另一个脚本应用于目录中的每个文件,如矩阵
【发布时间】:2015-06-08 21:47:53
【问题描述】:

假设我的目录中有五个文件。

文件:1、2、3、4 和 5

我有一个脚本,它将执行一个数学过程来比较两个文件,我想在目录中的每个文件上使用这个脚本,示例如下。

比较文件 1 和 2,3,4, & 5

比较文件 2 和 3,4, & 5

比较文件 3 和 4 & 5

比较文件 4 和 5

文件遵循此命名方案 filename_V0001.txt

如何编写一个简单的 bash 脚本来做到这一点?

【问题讨论】:

  • 我会将 glob 保存到一个数组中,获取它的长度,然后像在任何其他编程语言中那样循环索引,以避免像 Alfe 的答案中那样的黑客攻击。

标签: bash shell matrix scripting file-handling


【解决方案1】:

script_v1.sh:

#!/bin/bash
compare="/path/to/my/compare_tool"

for i in {1..5}; do
    for j in $(seq $((i+1)) 5); do
        echo "Comparing $i and $j"
        compare filename_V000$i.txt filename_V000$j.txt > result_$i_$j.txt
    done
done

result_v1:

$ > bash script_v1.sh
Comparing 1 and 2
Comparing 1 and 3
Comparing 1 and 4
Comparing 1 and 5
Comparing 2 and 3
Comparing 2 and 4
Comparing 2 and 5
Comparing 3 and 4
Comparing 3 and 5
Comparing 4 and 5
$ >

script_v2.sh:

#!/bin/bash
compare="/path/to/my/compare_tool"

for i in {1..100}; do
    for j in $(seq $((i+1)) 100); do
        fi="Filename_V$(printf "%04d" $i).txt"
        fj="Filename_V$(printf "%04d" $j).txt"
        if [[ -f "$fi" && -f "$fj" ]]; then
            echo "Comparing $fi and $fj"
            compare "$fi" "$fj" > result_$i_$j.txt
        fi
    done
done

result_v2:

$ > bash script_v2.sh
Comparing Filename_V0001.txt and Filename_V0002.txt
...
Comparing Filename_V0001.txt and Filename_V0100.txt
Comparing Filename_V0002.txt and Filename_V0003.txt
...
Comparing Filename_V0002.txt and Filename_V0100.txt
Comparing Filename_V0003.txt and Filename_V0004.txt
...
Comparing Filename_V0099.txt and Filename_V0100.txt
$ >

假设:

  • 从文件所在的路径调用脚本

【讨论】:

  • 我真的很喜欢这种方法,而且效果很好,谢谢。我将如何修改它以使其适用于 100 范围内的数字;所以我可以让它查看标记为 Filename_V0001.txt 到 Filename_V0100.txt 的文件?
  • @Chemist 不是程序员:我又添加了一个示例。
  • 这很有意义,但是当我在只有 15 个文件的目录上尝试它时,我在数字 0008 和 0009 处出现错误。我不知道为什么?
  • 一旦我在 Filename_V(ect...).txt 的数字前面添加了“V”,它就完美地工作了!谢谢!
【解决方案2】:
for a in *
do
  start=0
  for b in *
  do
    if [ "$start" = 1 ]
    then
      echo "Comparing $a with $b ..."
      diff "$a" "$b"
    elif [ "$a" = "$b" ]
    then
      start=1
    fi
  done
done

当然,文件的任何名称方案都可以在 glob 模式中给出,例如。 G。 for a in filename_V*.txt.

【讨论】:

  • 对,@TomFenech。解决了这个问题。
【解决方案3】:

一种相当通用的方法:

#!/bin/sh
for comp1; do
  shift
  for comp2; do
    echo "Comparing '$comp1' with '$comp2'"
    do_compare "$comp1" "$comp2"
  done
done

然后您可以调用该脚本与要比较的文件列表:

do_all_compares Filename_V*.txt

for x 等价于for x in "$@"。该列表是在执行for 语句时计算的,因此在循环开始时发生的shift 只会影响内部比较的列表。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    • 1970-01-01
    • 2017-01-26
    相关资源
    最近更新 更多