ls
似乎有许多对我来说很奇怪的限制,这些限制未包含在其开关中(例如--max-depth=
其他工具所具有的)。我喜欢维护通用标准(因此ls
并ll
遵循大多数普通发行版所具有的标准),但我的其他别名遵循某种易于记住的语法(lls
“长列表、安全性”等)。我可以将其分成几个不同的问题,但由于这一切都与寻找通用操作方法的尝试有关ls
,因此列出我的工作清单来描述我正在谈论的内容感觉更合适,因为它们都是相关的。一些具体问题:
我经常听到有人说你永远不应该
ls
在for
循环等中使用。这在默认情况下如何ls
查看子目录等方面是有意义的,但是有没有一种简单的方法可以剪辑ls
以从不查看子目录内部?我--max-depth=
在页面中没有看到任何类似的内容man
,但在我看来,如果我们剪辑ls
不进入子目录,那么在for
循环或其他结构中使用应该是可靠的。是否有一种可靠的方法来剪辑ls
为仅一个目录的输出,然后在 for 循环中使用它?我使用了我认为相当笨重的结构
lld
(带有目录的长列表)和llf
(带有文件的长列表)。有没有更好的方式来表达“我只想查看文件”?或“我只想查看目录?”;再次,man
页面中我看不到任何内容 。特别是,我只能以-l
格式进行此列表,否则我无法 grep 出我不想显示的项目。一般来说,我认为以这种方式使用 grep 可能是一个坏主意(因为锁定-l
格式),那么有没有更好的方法来实现仅选择目录项或仅选择文件,而不是使用 grep ?如果下面的任何其他方法格式错误,我希望知道更好的方法?
尝试拥有一组标准的ls
输出(每个发行版的设置通常不同)。
字符[]
集通配符。例如ls name[03][17].c
, 将匹配name01.c
, name07.c
, name31.c
, name37.c
, 并且[]
还允许范围:ls name[07][1-9].c
请注意使用 来\ls
运行裸命令,忽略别名。
将-F
一个指示符(其中之一*/=>@|
)附加到条目
color=always
vscolor=auto
。
ls
就递归而言非常尴尬,例如ls *
即使没有标志,也会查看每个子文件夹-R
,并且ls c*
会查看每个文件夹c
。
ls
切勿在 a 中使用 an 的输出,for i in ls
因为这可能是不可预测的。
不想对别名做任何晦涩的事情,请遵循广泛使用的ls
、ll
、的设置l
,然后为其他任务添加其他别名。
[[ $(type ls) == *"aliased"* ]] && then unalias ls
:不需要这个,但一般来说是测试类型以alias
对其采取行动alias ls='\ls --color=always --group-directories-first
':l
将在大多数发行版中打印正常内容ls
(即不会显示.*
文件!)。请注意,\
在命令恢复之前,命令会恢复其非别名形式。alias l='ls -AFh --color=always --group-directories-first'
:使用-A
(几乎所有,忽略./
和../
,但显示所有.*
文件,将其放在ls
几乎总是想查看.*
文件的位置)alias la='ls -Ah'
: 长格式(-AFh
以及-l
):请注意,上面的l
别名用于\ls
运行 ls bare 而不带标志(主要是删除-A
)alias ll='ls -lAh'
: 长格式(-AFh
以及-l
):请注意,上面的l
别名用于在没有标志的情况下裸\ls
运行ls
(-A
主要是删除)
alias l.='ls -d .*' # Explicitly list just .* files, so ./ and ../ are shown, overriding the A flag
alias ls.='ls -d .*' # Explicitly list just .* files, so ./ and ../ are shown, overriding the A flag, long format
alias ll.='ls -dl .*' # Explicitly list just .* files, so ./ and ../ are shown, overriding the A flag, long format
alias lld='ls -FlA | grep :*/' # Only directories
alias llf='ls -FlA | grep -v "/"' # Only files (broken as will show symlinks etc, if have to use `/`, then `/$` would be better, but using grep at all is probably not optimal)
alias ldot="ls -ld .??*" # Dotfiles only
alias lx="ls -FlA | grep *" # Executable files only, below 'lxext' is just trying to find 'executable-like' files by their extension
alias lnox="ls -FlA | grep -v *" # Everything except executable files
alias lxext='ll *.sh *.csh *.ksh *.c *.cpp *.py *.jar *.exe *.bat *.cmd *.com *.js *.vbs *.wsh *.ahk *.ps1 *.psm1 2> /dev/null' # List possible executables and scripts by extensions, discarding error output (as will generate for every type that is not there)
alias lext='ls -Fla | egrep "\."' # Files without extensions only ".|/"
alias lnoext='ls -Fla | egrep -v "\."' # Files without extensions only
alias lsp='find . -maxdepth 1 -perm -111 -type f' # List executable by permissions. ls -lsa | grep -E "[d\-](([rw\-]{2})x){1,3}" https://stackoverflow.com/q/7812324
alias lsum="ls -Fla \$1 \$2 \$3 \$4 \$5 | awk '{ print; x=x+\$5 } END { print \"total bytes = \",x }'" # ls on required info then awk will sum the sizes
alias lll='ls --human-readable --size -1 -S --classify' # Long-list with just size and name and total size summary line
alias lm='ls -Am'; alias lcsv='lm' # comma separated view (-m), -A almost all, except '.' and '..'
alias lsz='ls -lAshSr'; alias lsize='lsz' # -s size, -h human readable, -S by size, -r reverse so largest are easily visible at end
alias lt='ls -lAth' ; alias ltime='lt'; alias ldate='lt'; alias lst='lt' # sort by -t time/date, human readable
# replicate 'ls', but using 'stat' to show both normal 'ls' permission flags *and* octal.
lsec() { if [ -z "$@" ]; then args='. .*'; else args="$@"; fi; stat --printf="%A\t%a\t%h\t%U\t%G\t%s\t%.19y\t%n\n" $args; }; alias lstat='lsec';
lperm() { if [ -z "$@" ]; then args='. .*'; else args="$@"; fi; stat --printf="%A %a %n\n" $args; }; # Just permissions, %A (ls format), %a (Octal format) and names
sanitize() { chmod -R u=rwX,g=rX,o= "$@" ;} # Make directory and file access rights the same
alias 000='echo "---------- (Owner -, Group -, and Other -)"; chmod 000' # Remove permissions: append with file/directory to apply to
alias 644='echo "-rw-r--r-- (Owner rw, Group r, and Other r)"; chmod 644' # Onwer rw, everyone else read-only
alias 755='echo "-rwxr-xr-x (Owner rwx, Group r-x, and Other r-x)"; chmod 755' # Make executable, but only Owner has write permissions
alias mx='chmod a+x' # Make Executable
alias lls='lss' # Since the 'stat' output is in long format 'll', also use 'lls' for 'long listing with ecurity'
alias sl='ls' # Common typo, also just overwrite the 'Steam Locotomive' toy if present, as that gets boring
alias lg='exa -lG' # 'ls grid', exa is an interesting potential successor to 'ls', in Ubuntu 20.10 repo by default, colours each permission item and -lG is a useful 2x column long view.
if grep -qEi "(Microsoft|WSL)" /proc/version &> /dev/null; then
for d in /mnt/[a-z]; do [ -d /mnt/$(basename ${d}) ] && alias "$(basename ${d}):"="cd $d"; done # "d:" => cd to /mnt/d
for d in /mnt/[a-z]; do [ -d /mnt/$(basename ${d}) ] && alias "l$(basename ${d}):"="cd $d && ll"; done # "ld:" => cd to and list d:""
fi
答案1
反对使用的常见建议ls
不是关于for
循环,而是关于任何类型的输出解析ls
。这包括几乎肯定会因奇怪的文件名而失败的事情ls | grep
(例如,包含换行符或全局字符的文件名)。请仔细阅读https://mywiki.wooledge.org/ParsingLs和为什么*不*解析`ls`(以及该怎么做)?。
主要的一点是,您不想在循环或任何其他解析ls
中使用的原因for
与子目录无关,而与如何ls
显示其结果有关。也就是说,有一个标志会导致ls
(至少是 GNU ls
,Linux 上的默认设置)不进入子目录:
-d, --directory
list directories themselves, not their contents
例如:
$ tree
.
├── dir1
│ ├── file1
│ ├── file2
│ └── file3
└── dir2
├── file1
├── file2
└── file3
2 directories, 6 files
现在比较一下:
$ ls *
dir1:
file1 file2 file3
dir2:
file1 file2 file3
和
$ ls -d *
dir1 dir2
您已经在某些别名中使用了它。
至于lsd
和lsf
别名,是的,正如你所说,这很笨拙,而且对于奇怪的文件名也会失败。仅列出目录的“标准”方式是:
ls -d */
我不知道如何仅获取 basic 的文件ls
,如果您出于某种原因确实需要它,您可以使用find
:
find . -maxdepth 1 -type f
一般来说,ls
它是为人类而不是脚本而设计的。因此,如果您需要解析它,总是有更好的工具。通常find
或stat
.
其中一些别名根本不符合您的想法。这些,例如:
alias lx="ls -FlA | grep *" # Executable files only, below 'lxext' is just trying to find 'executable-like' files by their extension
alias lnox="ls -FlA | grep -v *" # Everything except executable files
由于别名会产生一个不带引号的*
,因此 shell 在grep
看到它之前就会对其进行扩展。因此,如果您有一个包含两个文件的目录:
$ ls
file1 file2
然后,lx
将实际运行
ls -FlA | grep file1 file2
因为*
会扩展到目录的内容,所以file1 file2
.结果是您的别名将完全忽略并使用 grep 查找文件中的ls
字符串。这两个的可行替代方案是:file1
file2
alias lx="find . -maxdepth 1 -executable -type f"
alias lnox="find . -maxdepth 1 -type f ! -executable"
浏览 28 个别名的列表远远超出了简单问答的范围,但这应该作为一个起点:忘记解析ls
,它不能安全地完成,你应该使用别名与find
orstat
代替。