在Unix(bash)中,如何将通配符附加到变量?

时间:2015-12-12 01:32:03

标签: bash unix

我有一份工作要求我遍历BigDirectory中的每个目录,然后遍历每个目录中的每个文件。所以喜欢:

for d in BigDirectory/*/
do
 FILES=$d*
 for f in $FILES
 do
  echo "File $f in directory $d"
 done
done

我的问题是关于FILES = $ d *。当我在命令行中执行此命令时,它的工作方式与它应该的一样 - 也就是说,对于单次迭代,echo $ FILES显示

BigDirectory/directory1/file1
BigDirectory/directory1/file2
BigDirectory/directory1/file3

但是当我将这个脚本作为一个作业提交到我的集群上时,它不起作用 - 如果我要回显$ FILES,我会看到它一直在寻找文字文件名为“BigDirectory / directory1 / *”的东西。 - 就像它没有注册星号一样。

任何人都知道可能会发生什么?

修改 对我有用的是在每个循环之前放入shopt -s nullglob,并在开头添加一行“cd以定义集群在哪里查找文件(因此它不会扩展*)。感谢您的帮助所有

2 个答案:

答案 0 :(得分:3)

如果通配符不匹配任何文件,则结果将是文字字符串本身。为了防止在设置 } public static void shuffleArray(int[] ar) { // If running on Java 6 or older, use `new Random()` on RHS here Random rnd = ThreadLocalRandom.current(); for (int i = ar.length - 1; i > 0; i--) { int index = rnd.nextInt(i + 1); // Simple swap int a = ar[index]; ar[index] = ar[i]; ar[i] = a; } } public static void menu() { System.out.println(); System.out.println("Select one of the following options"); System.out.println("1. Question 1"); System.out.println("2. Question 2"); System.out.println("3. Question 3"); System.out.println("4. Question 4"); System.out.println("5. Question 5"); System.out.println("6. Question 6"); System.out.println("7. Question 7"); System.out.println("8. Question 8"); System.out.println("9. Question 9"); System.out.println("10. Question 10"); System.out.println("11. Turn in Test"); System.out.println("12. Exit"); } public static void Quit() { System.out.println("Goodbye"); System.exit(0); } public static char Question(String reference) { Scanner input = new Scanner(System.in); System.out.println(reference); System.out.println("Please enter answer in caps"); char answer = input.next().charAt(0); System.out.println(answer); } public static int gradeTest(char key, char userAnswers) { int points; if (key == userAnswers) { points = 1; } else { points = 0; } return points; } } 选项的情况下运行,请改为使用nullglob循环中的通配符。

for

答案 1 :(得分:1)

当glob(通配符*的正确名称)与没有文件匹配时,它会保留,并且打印出来就好像是一个文件(不是)。
可以使用bash选项nullglob更改扩展globs的方式。如果设置,则glob消失,并且不用作文件。

此外,对每个目录使用$d/*是个好主意,您使用的表单很容易失败。如果它结束为两个//则没有问题,这些将被解析为好像使用了一个/

但是没有必要完成所有这些工作,这个简单的命令:

set -- BigDirectory/**;

将大列表中的所有文件(甚至内部目录和子目录)设置为位置参数。然后,一个循环就足够了。

所以,没有必要重新扫描每个目录,所有都可以用**(在bash中)完成:

shopt -s globstar nullglob
set -- BigDirectory/**;
for d;
do
    echo "$d";
done

如果要将选项恢复到原来的状态,请将(...)中的所有代码括起来。