Bash命令列出Linux上特定目录和子目录的名称

798qvoo8  于 5个月前  发布在  Linux
关注(0)|答案(3)|浏览(74)

我需要一个bash命令,搜索目录“rawdata”的所有子目录的名称开始与“AB”,搜索所有这些为“demo”和所有“demo”目录中的所有子目录的名称组成的只是数字。从所有这些我需要的文件的名称有“.txt”作为一个扩展。该命令总是只需要查看一个深度,而不是搜索更深.我试图在“test.txt”中写入所有找到的文件名,但我的代码不工作的权利。
我的方法:

find rawdata/AB* -type d -name 'demo' -exec find {} -mindepth 1 -maxdepth 1 -type d -regex '.*/[0-9]+' -exec find {} -mindepth 1 -maxdepth 1 -type f -name "*.txt" {} \; | awk -F/ '{print $NF}' > test.txt

字符串
我得到了这样的错误消息:

‘rawdata/AB.../q.../A.../demultiplexed’: No such file or directory


这对我来说是一个证明,它不首先搜索演示,因为它采取了EQUIPQ.进一步说,它没有采取一个文件夹与一个数字作为名称!
一个正确的路径应该是这样的:‘rawdata/AB.../demo/123/hereAndJustInThisLevelHereIsTheSearchedFile.txt’因此,在每个第一级目录必须有顺序“rawdata”,在第二级它应该只检查名称以“AB”开头的目录,在第三级只有一个“demo”,它应该只检查这个,在第四级它必须只检查所有目录,有一个数字作为文件夹名称!
我已经尝试了一些其他类似的代码版本,但没有一个给我正确的结果。

50pmv0ei

50pmv0ei1#

我仍然认为这个简单的find应该可以做到。

find -regex './rawdata/AB.*/demo/[0-9]+/.*\.txt'|awk -F/ '{print $NF}' > test.txt

字符串

inkz8wg9

inkz8wg92#

这段Shellcheck-clean代码演示了一种可能的方法,可以用纯POSIX shell做你想做的事情:

#! /bin/sh -

for txtfile in rawdata/AB*/demo/*/*.txt; do
    case $txtfile in
        rawdata/AB*/demo/*[!0-9]*/*.txt) : ;;
        *) [ -f "$txtfile" ] && printf '%s\n' "${txtfile##*/}" ;;
    esac
done

字符串

  • 有关rawdata/AB*/demo/*/*.txtrawdata/AB*/demo/*[!0-9]*/*.txt模式的解释,请参见POSIX Shell Command Language文档的模式匹配表示法部分。
  • rawdata/AB*/demo/*[!0-9]*/*.txt) : ;;导致跳过包含非数字字符的第3级子目录中的文件。
  • 有关${txtfile##*/}的解释,请参阅POSIX Shell Command Language文档的参数扩展部分。
  • 这段代码可以使用Bash,但如果它总是使用Bash运行,那么使用extglob特性来匹配数字目录名会更好(更短,更清晰)。
13z8s7eq

13z8s7eq3#

我需要一个bash命令,搜索到文件夹“rawdata”

find 'rawdata' -maxdepth 1

字符串
所有以“AB”开头的姓氏

find 'rawdata' -maxdepth 1 -type d -name 'AB*'


搜索在所有这命令的子文件夹“演示”

while IFS= read -r dir1; do
    find "$dir1" -maxdepth 1 -type d -name 'demo'
done < <(find 'rawdata' -type d -name 'AB*')


而在“演示”文件夹中,所有的名称都是由数字组成的。

while IFS= read -r dir1; do
    while IFS= read -r dir2; do
        find "$dir2" -maxdepth 1 -type d -regex '.*/[0-9]+$'
    done < <(find "$dir1" -maxdepth 1 -type d -name 'demo')
done < <(find 'rawdata' -maxdepth 1 -type d -name 'AB*')


从所有这些文件夹命名的一个数字,我需要的文件名,帽子“.txt”作为结束。

while IFS= read -r dir1; do
    while IFS= read -r dir2; do
        while IFS= read -r dir3; do
            find "$dir3" -maxdepth 1 -type f -name '*.txt'
        done < <(find "$dir2" -maxdepth 1 -type d -regex '.*/[0-9]*$')
    done < <(find "$dir1" -maxdepth 1 -type d -name 'demo')
done < <(find 'rawdata' -maxdepth 1 -type d -name 'AB*')


或者,你可以这样做:

shopt -s extglob
printf '%s\n' rawdata/AB*/demo/+([0-9])/*.txt


由于printf是一个内置的,如果有大量的文件,就不会像其他工具一样失败,如果文件的数量和名称的长度超过ARG_MAX
例如,给定以下目录结构:

$ mkdir -p rawdata/ABx/demo/17/
$ mkdir -p rawdata/ABy/demo/235
$ > rawdata/ABx/demo/17/foo.txt
$ > rawdata/ABx/demo/17/bar.txt
$ > rawdata/ABy/demo/235/whatever.txt


获取文件的完整路径:

$ while IFS= read -r dir1; do
    while IFS= read -r dir2; do
        while IFS= read -r dir3; do
            find "$dir3" -maxdepth 1 -type f -name '*.txt'
        done < <(find "$dir2" -maxdepth 1 -type d -regex '.*/[0-9]*$')
    done < <(find "$dir1" -maxdepth 1 -type d -name 'demo')
done < <(find 'rawdata' -maxdepth 1 -type d -name 'AB*')
rawdata/ABx/demo/17/bar.txt
rawdata/ABx/demo/17/foo.txt
rawdata/ABy/demo/235/whatever.txt
$ shopt -s extglob
$ printf '%s\n' rawdata/AB*/demo/+([0-9])/*.txt
rawdata/ABx/demo/17/bar.txt
rawdata/ABx/demo/17/foo.txt
rawdata/ABy/demo/235/whatever.txt

或者只是获取文件的名称:

$ while IFS= read -r dir1; do
    while IFS= read -r dir2; do
        while IFS= read -r dir3; do
            find "$dir3" -maxdepth 1 -type f -name '*.txt' -printf '%P\n'
        done < <(find "$dir2" -maxdepth 1 -type d -regex '.*/[0-9]*$')
    done < <(find "$dir1" -maxdepth 1 -type d -name 'demo')
done < <(find 'rawdata' -maxdepth 1 -type d -name 'AB*')
bar.txt
foo.txt
whatever.txt
$ shopt -s extglob
$ printf '%s\n' rawdata/AB*/demo/+([0-9])/*.txt | sed 's:.*/::'
bar.txt
foo.txt
whatever.txt

上面的代码假设您的文件或目录名都不包含换行符。

相关问题