是否可以根据可能列出的目录条目数使 ls 命令表现不同?
如果我只是使用ls
(没有修改选项,但我可以指定目录或过滤器),我希望它:
-l
如果条目数或少于 10 条,则采用长列表格式- 仅显示前 50 个条目并输出警告
x more entries
这可能吗?我怎样才能做到这一点?
请注意,我不想使用自定义脚本命令切换到自定义命令 - 我可以使用自定义脚本或包装器,但我仍然想使用ls
它来执行此操作,并且仍保留完整功能。也就是说,不仅仅是my-custom-ls
调用ls
脚本/包装器。
答案1
如果您不需要自定义脚本命令/包装函数,那么您需要自定义二进制命令。 GNUls
源代码以及其他实现都可用。
创建您自己的修补版本,ls
然后您就可以了。
请注意,这种行为变化会破坏 POSIX 合规性。
编辑(根据您修改后的问题):
ls() {
if [ $(command ls "$@" | wc -l) -gt 10 ]; then
command ls "$@" | head -50
else
command ls -l "$@"
fi
}
显示剩余条目数的增强版本:
ls() {
[ ! -t 1 ] && { command ls "$@" ; return ; }
r=$(command ls "$@")
lines=$(printf "%s" "$r" | wc -l)
if [ $lines -gt 10 ]; then
printf "%s" "$r" | head -50
if [ $lines -gt 50 ]; then
printf "%d more entries\n" $((lines - 50))
fi
else
command ls -l "$@"
fi
}
答案2
创建您自己的脚本(例如,在 Python 中),该脚本计算参数并ls(1)
使用正确的参数进行调用,并more(1)
根据需要进行分页(如果输出转到 tty)。
答案3
我无法重新定义 ls 本身,但您可以将此函数用于“ls2”:
ls2 () {
num_of_files=`ls | grep "\/$" | wc -l`
if [ "$num_of_files" -gt "10" ]; then
ls | less
else
ls -l
fi
}
创建一个自定义命令 ls2,它使用 grep 查找目录,然后使用 wc(带有行数选项的 unix 字数统计函数)来计算有多少个。您可以更改“10”比较中的文件数量。您可以通过更改ls -l
和/或ls -a
命令来更改实际执行的操作
如果您不熟悉 bash 函数 - 将代码放入文件中,然后chmod +x
将该文件使其可执行,然后运行该文件,. the_filename
然后使用该函数ls2
对于永久解决方案,将该函数添加到您的.bashrc
文件中(并考虑创建一个源自.bashrc
该文件的文件,以便您可以开始在一个位置添加更多函数,而不会让您的.bashrc
文件变得笨拙。
我不能一次少地显示条目。
答案4
这是我对这个问题的解释。它是 bash 特定的,因为它使用数组。它定义了一个名为的函数ls
(因此请务必运行unalias ls
以清除其执行的方式ls
)。该函数创建给定参数的数组(如果没有给出参数,则创建当前目录内容的数组);然后它对这些元素进行计数以确定ls
要使用哪些标志(小于 10,则使用ls -ld
;否则使用ls -d
);如果文件超过 50 个,则仅显示前 50 个,并显示一条消息。我还厚颜无耻地复制了 Kevin/jlliagre 的想法,让函数ls
在输出不输出到屏幕时表现得更正常。
这不允许将标志传递给 real ls
;诸如-r
和 之类的事情-a
需要特别照顾。
function ls {
_ls_longlimit=10
_ls_cutoff=50
declare -a _ls_files
[ ! -t 1 ] && { command ls "$@"; return; }
# TODO: skip past any "-rtxyz" options
if [ $# -eq 0 ]
then
_ls_files=(*)
else
for a in "$@"
do
if [ -d "$a" ]
then
# add "${a}/*" to array
_ls_files+=("${a}"/*)
else
# add $a to array
_ls_files+=("$a")
fi
done
fi
if [ ${#_ls_files[@]} -le $_ls_longlimit ]
then
command ls -ld "${_ls_files[@]}"
else
# -1 because arrays are 0-based
command ls -d "${_ls_files[@]:0:_ls_cutoff - 1}"
fi
if [ ${#_ls_files[@]} -gt $_ls_cutoff ]
then
echo $((${#_ls_files[@]} - _ls_cutoff)) more entries
fi
}