使用 find 或其他命令限制同一目录中文件扩展名的搜索

使用 find 或其他命令限制同一目录中文件扩展名的搜索

我有一个目录,其中有多个子目录。我正在一一循环子目录。然后我使用 cd 更改目录。如果在该子目录中,我有一个扩展名为 .partial 的文件,请保存文件名。然后我需要打印子目录名称和部分文件名。我写过这样的东西

for f in *
do
    if [ -d "$f" ]; then
        cd "$f"
        a=$(find ./ -name "*.partial")
        if [ -e "$a" ];then
            echo -e "$f" "\t" "$a"
        fi
        cd ..
    fi
done

问题是它会在进一步的子目录中find递归地查找文件扩展名,这是我不想要的。.partial如何将其限制为仅当前目录?

答案1

仅输出.partial相对于当前目录的每个文件的完整路径名:

printf '%s\n' ./*/*.partial

如果没有匹配,设置nullglobshell 选项将使其不输出模式本身(仍然会输出空行),并且设置还会匹配隐藏名称。bashdotglob


以下将这些路径名拆分为目录路径和文件名部分:

for name in ./*/*.partial; do
    [ -f "$name" ] && printf '%s\t%s\n' "${name%/*}" "${name##*/}"
done

这将打印在当前目录的任何子目录中找到的.partial每个名称的子目录名称和文件名。.partial

在 中,如果您还需要能够匹配隐藏名称,bash您可能还需要设置 shell 选项。dotglob

dirname这两个参数替换可以通过调用和来替换basename

for name in ./*/*.partial; do
    [ -f "$name" ] && printf '%s\t%s\n' "$(dirname "$name")" "$(basename "$name")"
done

上述内容的变体,仅打印一次子目录名称(这需要一个bash类似 shell 的${*%%*/}参数扩展,它为每个位置参数删除目录路径并保留文件名):

IFS=$'\t'
for dirname in ./*/; do
    set -- "$dirname"/*.partial;
    [ -f "$1" ] && printf '%s\t%s\n' "$dirname" "${*##*/}"
done

这会循环遍历每个子目录并扩展*.partial每个子目录中的通配模式。如果第一个匹配是常规文件(或某个文件的链接),则打印子目录名称,后跟与模式匹配的名称,并删除目录路径。

答案2

find实用程序支持该选项-maxdepth

-max深度级别
下降到起始点以下目录的最多级别(非负整数)级别。 -maxdepth 0 表示仅将测试和操作应用于起点本身。

要限制find到指定目录,可以添加选项-maxdepth 1


如果您尝试列出*.partial深度为 2 的所有常规文件,其输出与您的问题中的输出类似,您可以尝试以下命令

 find . -mindepth 2 -maxdepth 2 -type f -name '*.partial' -printf '%h\t./%f\n'

这可能会给出类似的输出

./b    ./file2.partial
./b    ./file3.partial
./a    ./file1.partial

答案3

如果你有 GNUfind你可以做这样的事情

for dir in *
do
    files=$(find "$dir" -maxdepth 1 -type f -name '*.partial' -printf "%f\n" | xargs)
    [[ -n "$files" ]] && printf "%s\t%s\n" "$dir" "$files"
done

如果你没有 GNU,你可以以牺牲一些效率为代价来find模拟,就像这样-printf '%f\n'

for dir in *
do
    files=$(cd "$dir" && find . -maxdepth 1 -type f -name '*.partial' -print | sed 's!^./!!' | xargs)
    [[ -n "$files" ]] && printf "%s\t%s\n" "$dir" "$files"
done

这两种解决方案都不能处理带有换行符或奇怪打印字符的文件,但如果您在单行上列出目录中的文件,我希望您不会有奇怪的文件名。如果您的 shell 无法理解,[[ ... ]]只需将双括号替换为单括号即可[ ... ]

相关内容