使用通配符检查文件是否存在于多个目录中

时间:2019-12-17 18:41:43

标签: linux bash

我有大约10,000个目录。它们中的大多数都有一个类似名称的文本文件。 我想获取这些.txt文件并将其复制到主目录ALL_RESULTS中的文件夹中。我怎样才能做到这一点?我下面有什么

for d in *_directories/; do

  #go into directory
  cd "$d"

  #check if file exists using wildcard, then copy it into ALL_RESULTS and print the name of 
  #directory out
  if ls *SCZ_PGC3_GWAS.sumstats.gz*.txt 1> /dev/null 2>&1; then
    cp *SCZ_PGC3_GWAS.sumstats.gz*.txt ../ALL_RESULTS && echo "$d"

  #if file does not exist, print the name of the directory we're 
  #in
  else
    echo "$d"
    echo "files do not exist"
  cd ..
  fi
done

我不断收到错误消息,指出目录本身不存在。我在做什么错了?

2 个答案:

答案 0 :(得分:1)

所有相对路径都相对于您所在的目录(“当前工作目录”)进行解释。因此,想象一下,您进入了第一个目录。现在,您位于该目录中。然后循环执行,然后尝试cd进入第二个目录。但是该目录不再是,您需要“向上”,然后cd进入该目录。这就是该目录不存在的原因-您必须为cd进入的每个目录“上”一个目录。

因此,您需要在循环结束时cd ..回到您从其开始的目录。

  

我有大约10,000个目录。 ...我想获取这些.txt文件并将其移动到主目录ALL_RESULTS

中的文件夹中

如果您不需要输出任何内容,只需使用find并使用适当的正则表达式即可。进行lscd循环会非常慢。沿途:

find . -maxdepth 2 -type f -regex '\./.*_directories/.*SCZ_PGC3_GWAS.sumstats.gz.*\.txt' -exec cp {} ALL_RESULTS \;

您还可以将-v添加到cp来查看其复制内容。

答案 1 :(得分:-1)

您想念

shopt -s nullglob

不要解析输出:

#!/bin/bash

shopt -s nullglob

for d in *_directories/; do
  # check if file exists using wildcard, then copy it into ALL_RESULTS and print
  # the name of directory
  files=$( $d/*SCZ_PGC3_GWAS.sumstats.gz*.txt )
  if [[ ${files[@]} ]]; then
    cp "${files[@]}" ALL_RESULTS && echo "$d"

  #if file does not exist, print the name of the directory we're 
  #in
  else
    echo "$d"
    echo "files do not exist"
  fi
done