如何列出不带目录的文件并按名称过滤(ls选项)


42

我有一个名为的目录uploads。它包含一堆文件以及一些子目录,这些子目录又包含文件。

有什么办法可以(一步)执行以下操作:

  1. 仅列出根上载目录中的文件-我不想看到子文件夹名称或其内容;

  2. 不要列出任何以 t_

我知道该-d标志,但并不能完全满足我的需求。

Answers:


53

这听起来像是一份工作find

  • 使用-maxdepth只返回当前目录,里面的子文件夹不recursivly搜索
  • 使用-type f仅返回文件,而不是目录或设备节点或其他任何
  • 如果-not-name避免出现名称不需要的文件,请结合使用

它可能像这样合并在一起:

find /path/to/uploads -maxdepth 1 -type f -not -name 't_*'

谢谢!我对CLI还是很陌生,以前从未使用过find。我一定会进一步研究它。
EmmyS 2011年

2
@EmmyS:您可能会在这里发现另外一个小技巧。@Gilles -exec ls -lG -- {} +在他的答案中提到了使用ls的额外选项来获取输出。您也可以-ls在此查找中添加一个,以快速粗略地了解ls的详细视图。
卡莱布

18

GNU ls(即,非嵌入式Linux系统和Cygwin上的ls命令,也可在其他unices上使用)具有根据文件名隐藏某些文件的选项。但是,无法忽略目录。

ls --hide='t_*' uploads

另一种方法是使您的外壳进行匹配。Bash,ksh和zsh具有一个否定模式!(t_*)以匹配除匹配文件以外的所有文件t*;在bash中,此功能需要启用shopt -s extglob,在zsh中,需要启用setopt ksh_glob。Zsh还具有^t_*需要使用开启的等效语法setopt extended_glob。这仍然不会忽略目录。Zsh有一个额外的功能,它不仅可以按名称匹配文件,还可以按元数据和其他匹配文件:glob限定符(.)在比赛结束时添加以限制为常规文件。否定^是名称匹配语法的一部分,因此^t_*(.)表示“所有常规文件均不匹配t_*”,而不是“所有常规文件均不匹配t_*”。

setopt extended_glob  # put this in your ~/.zshrc
ls uploads/^t_*(.)

如果您发现自己没有高级工具,则​​可以使用在任何unix上执行此操作find。这不是您通常在命令行上键入的内容,但功能强大且精确。Caleb已经展示了如何使用GNU find做到这一点。该-maxdepth选项不可移植;您可以改-prune而使用,以方便地停止find递归。

find uploads/* -type d -prune -o \! -type f -name 't_*' -print

替换-print-exec ls -lG -- {} +ls对文件执行您喜欢的选项。

上面的所有命令都隐藏点文件(即名称以开头的文件.)。如果要显示它们,请传递-Als,或D在zsh(ls uploads/^t_*(.D))中添加glob限定符。使用find,您可以使用另一种方法,使其仅递归一个级别(find不专门处理点文件)。仅当您find在当前目录中运行时,这才完全起作用。

cd uploads && find . -name . -o -type d -prune -o \! -type f -name 't_*' -print

3
你有工作吗?;-)我对您答案的详细程度和水平感到惊讶,甚至对Unix SE上最简单的问题也是如此!:)
Alex

谢谢!很详细。我不知道我是否拥有“高级工具”。我在Mac上工作(尽管Linux在家里,所以我肯定这会在某些时候派上用场。)
EmmyS 2011年

@EmmyS:对于您的Linux机器,我使用的-maxdepth应该可以使用,但是Gilles提到的“可移植性”问题是BSD find(我认为也在OSX上找到)有点不同,所以您可能也需要他的回答。@Gilles:zsh技巧+1!
卡莱布

1
@Gilles:prune我想到了一些关于s的不那么多汁的评论,但是我只是简单地说,当我在自己的系统上乱搞的时候,认为“ 如果我在运行此命令,该命令会起作用 ”的次数“ AIX,Solaris或MINIX3 ”大约是...待机...我很难读到电表...显示器被冻结0.00
卡莱布

2
Gnu ls没有--use-telepathy选择权吗?这是仅显示所需文件的最快方法。它可能不是便携式的。
dubiousjim 2012年



0

让我用lsand管道试一下:

ls  -l --hide='t_*'  uploads/ | grep -v ^d | tr -s ' ' | cut -d ' ' -f 9

说最后一列是第9列。


1
如果文件中有空格怎么办?
jordanm 2012年

0

如果担心find的-maxdepth可移植性问题,则可以使用:

ls -l uploads/ | awk '/^-/ && $9 !~/^t_/ {print $9}'

我不是专家,但我认为这应该可行。我想它看起来有些神秘,但是如果您说awk,实际上不是。可以使用$ NF代替$ 9。您也可以这样做:

ls -l uploads/ | awk '/^-/' | awk '!/^t_/ {print $9}'

哪个做同样的事情(但效率可能不如前一个???)。

实际上,在考虑了其他帖子之后,

ls -l --hide=t_* uploads/ | awk '/^-/ {print $9}'

是更短更清晰的方法。

如果我错了,请有人纠正我。:-)


解析ls通常不是一个好主意。例如,您的awk技巧将因包含空格的文件名而失败。
2013年

@mat-感谢您的纠正。阅读了您(和jw013)指出的文章之后,我发现ls无法被信任来输出正确的文件名。即使我要重写awk代码以打印从$ 9到行尾(包括空格)的所有内容,此ls输出可能仍然是错误的。这令人失望,应纠正IMO。再次感谢。
kkaszub


-1

试试这个别名并使用它:

alias l='ls -hLlF'

ls -hLlF确实显示了子目录,并且确实显示了以t_。开头的文件。那么这如何回答这个问题呢?
拉斐尔·阿伦斯

也许我误解了这个问题。ls -hLlF将不显示链接目录的目标目录。
粒度

似乎如此。但是,您还没有阅读有关该问题的其他答案吗?
拉斐尔·阿伦斯

-1

十分简单:

ls -l --hide 't_*' <absolute path to desired directory> | grep -v ^d


(1)这个答案很简单,以前已经给出过。(2)为什么您认为需要指定目录的完整路径?
斯科特(Scott)

@Scott-这是一种非常快速,简单的解决方案。指定了完整的路径以使答案变得普遍...
Digger
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.