[英]Recursively differentiating files and directories in bash
Bash here. 在这里重击。 Looking to write a script that: 寻找编写一个脚本,该脚本:
Found a file called $file!
" (where $file
is the name of the file) 如果它的直接子级之一是文件,我希望它回显“ Found a file called $file!
”(其中$file
是文件名) Found a directory named $dir
" (where $dir
is the name of the directory), but then I want it to recursively execute with this same exact logic inside that directory, and finally I want it to continue looping through the rest of the target directory 否则,如果它的直接子级之一本身就是目录,我希望它回显“ Found a directory named $dir
”(其中$dir
是$dir
的名称), 但是然后我希望它以相同的方式递归执行该目录中的逻辑,最后我希望它继续遍历目标目录的其余部分 Hence given the following target directory structure: 因此,给出以下目标目录结构:
~/testDir/
1.txt
2.txt
childDirA/
foo.png
3.txt
childDirB/
buzz.gif
childDirC/
foo.bar
4.txt
The output of the script would be: 该脚本的输出为:
Found a file called 1.txt!
Found a file called 2.txt!
Found a directory named childDirA
Found a file called foo.png!
Found a file called 3.txt!
Found a directory named childDirB
Found a file called buzz.gif!
Found a directory named childDirC
Found a file called foo.bar!
Found a file called 4.txt!
So far the best I've been able to come up with is: 到目前为止,我能想到的最好的方法是:
#!/bin/bash
for file in $1;
do echo "Found a file called $file";
done
However if I point this at my testDir
the only output I get is: 但是,如果我将此指向我的testDir
则得到的唯一输出是:
Found a file called testDir
Any ideas where I'm going awry? 有什么想法我要去哪里吗?
Here's a script that'll do that. 这是将执行此操作的脚本。
function listDir() {
for file in "$1"/*;
do
if [ -f "$file" ]; then
echo "Found file $(basename "$file")"
elif [ -d "$file" ]; then
echo "Found directory $(basename "$file")"
listDir "$file"
fi
done
}
listDir "$1"
As Tripp mentioned in the comments, find
can do the 'recursive' work for you; 正如Tripp在评论中所述, find
可以为您完成“递归”工作; then you just need to tweak the output into the format you want. 那么您只需要将输出调整为所需的格式即可。
Assuming you only need to worry about files and directories: 假设您只需要担心文件和目录:
#!/usr/bin/bash
while IFS= read -d "" -r tgt
do
# for printing purposes, strip off directory info; basically simulate
# `basename` without the overhead of spawning an expensive sub-process
tgtname=${tgt##*/}
# determine tgt's type : 'file' or 'directory'
tgttype='file'
[ -d "${tgt}" ] && tgttype='directory'
echo "Found a ${tgttype} named ${tgtname}"
done < <(find "$1" -print0)
NOTES: 笔记:
find $1
by itself to see the format of the data being fed into the loop 单独运行find $1
以查看送入循环的数据的格式 tgttype
if you're dealing with links, devices, etc (perhaps use a case
statement?) 如果要处理链接,设备等,则添加其他测试以确定tgttype
(也许使用case
语句?) find
to fine tune the list that's fed into the loop 考虑附加的命令行参数/ PARAMS来find
微调是美联储进入循环列表 #!/bin/sh
find "$1" -mindepth 1 -type f -printf 'Found a file called %f!\n' -o -type d -printf 'Found a directory named %f\n'
By default, find
recurses through subdirectories. 默认情况下,通过子目录find
递归。
Arguments to find
: find
参数:
-mindepth 1
Exclude the base directory -mindepth 1
排除基本目录 -type f ...
If a normal file is found, do the following -type f ...
如果找到普通文件,请执行以下操作 -o -type d ...
Or, if a directory is found, do the following -o -type d ...
或者,如果找到目录,请执行以下操作 -printf ...
Print according to the given format string -printf ...
根据给定的格式字符串打印 %f
The basename of the file (dirs are files in this context) %f
文件的基本名称(目录是此上下文中的文件)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.