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
script to traverse through directories and subdirectories to list files
提问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 if
and [
. 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 find
to 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 f
matches files only. -print0
combined 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" 的调用。
##代码##