bash 遍历目录和子目录以列出文件的脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18360000/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 06:20:15  来源:igfitidea点击:

script to traverse through directories and subdirectories to list files

linuxbashsubdirectory

提问by Komal Rathi

#!/bin/bash
#script to loop through directories to merge files

mydir=/data/
files="/data/*"

for f in $files
do
    if[ -d "$f" ]
    then
            for ff in $f/*
            do
                    echo "Processing $ff"
            done
    else
            echo "Processing $f"
    fi
done

I have the above code to go through directories and sub-directories and list all the files. I am getting the error: syntax error near unexpected token `then'

我有上面的代码来遍历目录和子目录并列出所有文件。我收到错误:语法错误接近意外标记`then'

What am I doing wrong here?

我在这里做错了什么?

回答by John Kugelman

if [ -d "$f" ]
  ^

There needs to be a space between ifand [. If you don't have a space, bash thinks you're trying to execute a command named if[.

if和之间需要有一个空格[。如果您没有空格,bash 会认为您正在尝试执行名为if[.



files="/data/*"
for f in $files

Also know that this won't work. To store a wildcard expansion in a variable like that you need to use an array. The syntax is a bit hairier...

也知道这行不通。要将通配符扩展存储在这样的变量中,您需要使用数组。语法有点毛茸茸的......

files=(/data/*)
for f in "${files[@]}"

Or you could write the wildcard inline the way you do with the inner loop. That would work fine.

或者您可以像处理内部循环一样内联编写通配符。那会工作得很好。

for f in "$mydir"/*


For what it's worth, you could use findto recurse through all files and sub-directories recursively.

对于它的价值,您可以使用find递归遍历所有文件和子目录。

find /data/ -type f -print0 | while read -d $'
# find all files either in /data or /data/subdir
find  /data -type f -maxdepth 2 | while read file; do
  echo $file;
end
' file; do echo "Processing $file" done

-type fmatches files only. -print0combined with -d $'\0'is a way to be extra careful with file names containing characters like spaces, tabs, and even newlines. It is legal to have these characters in file names so I like to write my scripts in a way that can handle them.

-type f仅匹配文件。-print0结合使用-d $'\0'是一种对包含空格、制表符甚至换行符等字符的文件名格外小心的方法。在文件名中包含这些字符是合法的,所以我喜欢以一种可以处理它们的方式编写我的脚本。

Note that this will recurse deeper than just sub-directories. It'll go all the way down. If that's not what you want, add -maxdepth 2.

请注意,这将比子目录更深入地递归。它会一直下降。如果这不是您想要的,请添加-maxdepth 2.

回答by John Ledbetter

As an alternative, you could probably replace this entire loop with something like

作为替代方案,您可能可以用类似的东西替换整个循环

    # --- -------------------------------- --- #
    # FUNC:  Process a folder of files
    # --- -------------------------------- --- #
    func_process_folder_set(){

        FOLDER=""

        while read -rd $'##代码##' file; do

            fileext=${file##*.}  # -- get the .ext of file
            case ${fileext,,}    # -- make ext lowercase for checking in case statement
            echo "FILE: $file"   # -- print the file  (always use " " to handle file spaces)

        done < <(find  ${FOLDER} -type f -maxdepth 20 -name '*.*' -print0)

    }

    # -- call the function above with this:
    func_process_folder_set "/some/folder"

回答by Mike Q

Here's a function that does what you ask, you pass it a folder see the call at the bottom func_process_folder_set "/folder".

这是一个执行您要求的功能,您将其传递给一个文件夹,请参阅底部 func_process_folder_set "/folder" 的调用。

##代码##