作为一项练习,我为自己设置了使用bash builtins递归列出文件的任务。我特别不想使用ls或find,我宁愿不使用setopt extendedglob。以下似乎工作,但我看不到如何使用/.*扩展它以列出隐藏文件。有一个简单的解决方法吗?
g() { for k in "$1"/*; do # loop through directory
[[ -f "$k" ]] && { echo "$k"; continue; }; # echo file path
[[ -d "$k" ]] && { [[ -L "$k" ]] && { echo "$k"; continue; }; # echo symlinks but don't follow
g "$k"; }; # start over with new directory
done; }; g "/Users/neville/Desktop" # original directory
稍后添加:抱歉 - 我应该说:' bash-3.2 on OS X'
答案 0 :(得分:2)
更改
for k in "$1"/*; do
到
for k in "$1"/* "$1"/.[^.]* "$1"/..?*; do
第二个glob匹配所有名称以点开头,后跟除点之外的文件的文件,而第三个匹配所有名称以两个点后跟的东西的文件。在他们两个之间,他们将匹配条目.
和..
以外的所有隐藏文件。
不幸的是,除非设置了shell选项nullglob
,否则那些(如第一个glob)可以保持原样,如果没有名称匹配的文件(非常可能是第三个),所以它有必要验证该名称实际上是一个文件。
另一种方法是使用更简单的glob "$1"/.*
,它总是匹配.
和..
目录条目,因此总是被替换。在这种情况下,有必要从列表中删除两个条目:
for k in "$1"/* "$1"/.*; do
if ! [[ $k =~ /\.\.?$ ]]; then
# ...
fi
done
("$1"/*
仍然可以留在列表中。所以这并没有多大帮助。)
答案 1 :(得分:1)
将GLOBIGNORE文件设置为排除.
和..
,这会隐式启用" shopt -u dotglob"。然后您的原始代码无需任何其他更改。
user@host [/home/user/dir]
$ touch file
user@host [/home/user/dir]
$ touch .dotfile
user@host [/home/user/dir]
$ echo *
file
user@host [/home/user/dir]
$ GLOBIGNORE=".:.."
user@host [/home/user/dir]
$ echo *
.dotfile file
请注意,这是特定于bash的。特别是,它在ksh中不起作用。
答案 2 :(得分:0)
您可以为ProgrammingError: SELECT DISTINCT ON expressions must match initial ORDER BY expressions
指定多个参数:
for
但是如果您在目录中搜索for k in "$1"/* "$1"/.*; do
,您应该知道它还会为您提供.*
和.
个文件。如果..
glob匹配,也可能会给你一个不存在的文件,所以我也会检查它。
考虑到这一点,这就是我纠正循环的方法:
"$1"/*
这里看起来很时髦的g() {
local k subdir
for k in "$1"/* "$1"/.*; do # loop through directory
[[ -e "$k" ]] || continue # Skip missing files (unmatched globs)
subdir=${k##*/}
[[ "$subdir" = . ]] || [[ "$subdir" = .. ]] && continue # Skip the pseudo-directories "." and ".."
if [[ -f "$k" ]] || [[ -L "$k" ]]; then
printf %s\\n "$k" # Echo the paths of files and symlinks
elif [[ -d "$k" ]]; then
g "$k" # start over with new directory
fi
done
}
g ~neville/Desktop
只是获取文件基本名称的快捷方式,同时放入${k##*/}
以便变量不会修改任何现有变量外壳
我改变的另一件事是local
到echo "$k"
,因为printf %s\\n "$k"
在其参数处理中无可挽回地存在缺陷,应该避免为了回显未知变量。 (有关如何解释,请参阅Rich's sh tricks;它归结为-n和-e在工作中抛出扳手。)
顺便说一句,这不会打印套接字或fifos - 这是故意的吗?