Bash 遍历目录中的所有文件时出现问题

Bash 遍历目录中的所有文件时出现问题,bash,ubuntu,Bash,Ubuntu,Bash脚本的部分预期功能是接受目录名,然后遍历每个文件 以下是我的部分代码: #! /bin/bash # sameln --- remove duplicate copies of files in specified directory D=$1 cd $D #go to directory specified as default input fileNum=0 #save file numbers DIR=".*|*" for f in $DIR #for every file

Bash脚本的部分预期功能是接受目录名,然后遍历每个文件

以下是我的部分代码:

#! /bin/bash
# sameln --- remove duplicate copies of files in specified directory

D=$1
cd $D #go to directory specified as default input

fileNum=0 #save file numbers

DIR=".*|*"
for f in $DIR #for every file in the directory
do
    files[$fileNum]=$f #save that file into the array
    fileNum=$((fileNum+1)) #increment the fileNum

    echo aFile
done
echo语句用于测试目的。我将包含四个常规文件的目录名作为参数传递,我希望我的输出如下所示:

阿菲尔

阿菲尔

阿菲尔

阿菲尔

但是echo语句只显示一次。

使用find进行此操作,非常适合

find <dirname> -maxdepth 1 -type f -exec echo "{}" \;
请注意,最后一行与find$1-maxdepth 1-type f-print0相同

执行多项任务

使用find one还可以通过管道连接到xargs或在读取时执行多个任务,但我更喜欢使用函数。例如:

#!/bin/bash

function dostuff {
    # echo filename
    echo "filename: $1"
    # remove extension from file
    mv "$1" "${1%.*}"
    # get containing dir of file
    dir="${1%/*}"
    # get filename without containing dirs
    file="${1##*/}"
    # do more stuff like echoing results
    echo "containing dir = $dir and file was called $file"
}; export -f dostuff
# export the function so you can call it in a subshell (important!!!)

find . -maxdepth 1 -type f -exec bash -c 'dostuff "{}"' \;
请注意,如您所见,该函数需要导出。这样您就可以在子shell中调用它,该子shell将通过执行bash-c“dostuff”打开。为了测试它,我建议您对dostuff中的mv命令发表评论,否则您将删除所有扩展哈哈

还要注意,这对于文件名中的空格等奇怪字符是安全的,所以不用担心

闭幕词


如果您决定使用find命令,这是一个很好的选择,我建议您仔细阅读它,因为它是一个非常强大的工具。一个简单的男人会教你很多,你会学到很多有用的选择。例如,一旦找到结果,您就可以退出find,这可以方便地检查dir是否包含视频,例如快速地检查dir是否包含视频。这确实是一个了不起的工具,可以在各种场合使用,而且通常使用类似于awk的一行程序。

如果您只迭代单个目录下的文件,最好使用简单的文件名/路径扩展来避免某些不常见的文件名问题。以下内容将遍历作为第一个默认参数传递的给定目录中的所有文件。/:


如果您必须在包含多个分支的整个子树下迭代,那么查找可能是您唯一的选择。但是,请注意,使用find或ls填充for循环可能会带来嵌入字符的问题,例如文件名中的a\n等。请查看原因,即使有时不可避免。

您可以直接将文件读取到数组中,然后对其进行迭代:

#! /bin/bash
cd $1
files=(*)

for f in "${files[@]}"
do
    echo $f
done

我喜欢你的答案是如何保存空间的,比用$ls表示的f要好得多!公平地说,这是对find的不当使用,我认为find是迄今为止迭代文件和dir的最佳工具。因为我用$find。。。这绝对不是不可避免的。这里面有很多双重否定。如果在给定目录下有多棵不同深度的树,并且需要对这些文件进行迭代,您认为最好的方法是什么?我明白了,你是说用find查找文件是一种方法,我同意,但是对于遍历找到的列表,那又怎么样?通过-exec或-execdir调用脚本?xargs?对不起,我没听懂。迭代找到什么列表?-通过-exec调用脚本从来没有遇到过问题,我在很多情况下都会继续这样做。首选项,-exec还是-execdir?xargs?我更喜欢-exec,也见过很多人使用xargs,但我从未遇到过-exec没有做到这一点的情况。我不是说没有这样的情况,我只是从来没有经历过像上帝一样的复杂,哈哈哈。谢谢。您能解释一下我如何将多个命令传递给-exec吗?如果我想将找到的文件的内容加载到一个数组中,我需要多行来完成。或者,如果它可重复使用超过此脚本的内容,则只需将其另存为脚本并调用它即可。事实上,该注释为+1。事实上,以这种方式思考是很重要的,重用代码总是有益的。
#!/bin/bash

srchdir="${1:-.}"

for i in "$srchdir"/*; do

    printf " %s\n" "$i"

done
#! /bin/bash
cd $1
files=(*)

for f in "${files[@]}"
do
    echo $f
done