【问题标题】:How to list only files and not directories of a directory Bash?如何仅列出文件而不是目录 Bash 的目录?
【发布时间】:2012-05-21 10:24:17
【问题描述】:

如何列出一个文件夹的所有文件,但不列出其文件夹或子文件。换句话说:我怎样才能只列出文件?

【问题讨论】:

标签: bash file-listing


【解决方案1】:

使用find:

find . -maxdepth 1 -type f

使用-maxdepth 1 选项可确保您仅查看当前目录(或者,如果您将. 替换为某个路径,则为该目录)。如果您想要该目录和子目录中所有文件的完整递归列表,只需删除该选项即可。

【讨论】:

  • 在我对 mklement0 的回答发表评论后,我意识到“find ./*.png -maxdepth 1 -type f > pngs.txt”可能会达到同样的效果。确实如此。无需安装脚本。
  • find 在 mac 上,既没有 -type 也没有 -maxdepth 选项。
  • @Tim: -type-maxdepth 不是正常意义上的options; BSD find(在 OS X 上使用)称它们为 primaries,并且它们必须在文件名操作数之后(在这种情况下为.;注意与 Linux 不同,BSD 版本需要至少一个显式文件名操作数);此答案中的命令绝对适用于 Mac。
  • @AlexHall:这是一个聪明的解决方案(尽管我建议find *.png -maxdepth 0 -type f 避免在输出文件名中使用./ 前缀;还要注意0-maxdepth,而不是1) ,只要您需要的是字母顺序中的文件names。如果您想要 ls 可以为您做的其他事情(不同的输出格式/排序,对是否包含隐藏项目的内联控制),辅以 [多] 类型过滤,我的回答中的脚本可以提供帮助。跨度>
  • find * -maxdepth 0 -type f(来自@AlexHall 评论的替代方案)与find . -maxdepth 1 -type f 进行对比:find . ... 总是包含隐藏项,总是在输出文件名前加上./,并且, GNU find (Linux),通常输出一个未排序的列表。 find * ...,由于让 shell 预先执行 globbing,默认情况下排除隐藏项(可以使用 shopt -s dotglob 更改),仅输出文件名(无前缀),按字母顺序排序。这两种方法都不包括 文件的符号链接;使用选项-L 这样做。
【解决方案2】:

您还可以将lsgrepegrep 一起使用,并将其作为别名放入您的个人资料中:

ls -l | egrep -v '^d'
ls -l | grep -v '^d'

【讨论】:

  • 由于上面给出的原因,我不会把它放在脚本中,而是另一个快速而肮脏的解决方案:ls -F | grep -v '/$'
【解决方案3】:

只是添加到 carlpett 的答案。 要获得非常有用的文件视图,您可以将输出通过管道传输到 ls。

find . -maxdepth 1 -type f|ls -lt|less

以列表格式显示最近修改的文件,当您下载了大量文件并希望查看最近文件的整洁版本时非常有用。

【讨论】:

  • 这可能与您预期的不一样! ls 不读取标准输入,因此将任何内容通过管道传输到 ls 是没有用的。你错过xargs了吗?
  • 换一种说法:这个答案中的find 命令被完全忽略;整体命令和ls -lt | less一样,执行no类型过滤。
  • 虽然使用 GNU find 你可以做到 find . -maxdepth 1 -type f -ls。它似乎也适用于 Mac OS,但我认为 -maxdepth-ls 不是适当的可移植选项。
【解决方案4】:
  • carlpett's find-based answer (find . -maxdepth 1 -type f) 原则上有效,但与使用ls 不太一样:您会得到一个可能未排序 的文件名列表,所有文件名都带有前缀使用./,您将无法应用ls 的许多选项
    find 总是也发现隐藏,而ls'的行为取决于-a或@的存在与否987654339@ 选项。

    • Alex Hall 在对该问题的评论中建议的改进是将shell globbingfind 结合起来:: p>

          find * -maxdepth 0 -type f  # find -L * ... includes symlinks to files
      
      • 但是,虽然这解决了前缀问题并为您提供按字母顺序排序的输出,但您仍然无法(内联)控制包含隐藏项,也无法访问 ls 的许多其他排序 /输出格式选项。
  • Hans Roggeman's ls + grep answer 是实用的,但会限制您使用长 (-l) 输出格式


为了解决这些限制,我写了fls (filtering ls) utility

  • 一个实用程序,可提供ls输出灵活性,同时还提供类型过滤功能
  • 只需在 @987654351 列表之前放置 类型过滤字符,例如 f 用于文件,d 用于目录,l 用于符号链接 @arguments(运行 fls --helpfls --man 了解更多信息)。

示例:

fls f        # list all files in current dir.
fls d -tA ~  #  list dirs. in home dir., including hidden ones, most recent first
fls f^l /usr/local/bin/c* # List matches that are files, but not (^) symlinks (l)

安装

支持的平台

  • npm 注册表 安装时:Linuxma​​cOS
  • 手动安装时:使用 Bash 的任何 类 Unix 平台

来自npm registry

注意:即使你不使用 Node.js,它的包管理器 npm 也可以跨平台工作并且易于安装;试试
curl -L https://git.io/n-install | bash

安装Node.js,如下安装:

[sudo] npm install fls -g

注意

  • 是否需要sudo取决于你安装Node.js/io.js的方式以及是否有changed permissions later;如果您收到 EACCES 错误,请使用 sudo 重试。

  • -g 确保global installation 并且需要将fls 放入系统的$PATH

手动安装

  • this bash script 下载为fls
  • 使用chmod +x fls 使其可执行。
  • 将其移动或符号链接到$PATH 中的文件夹,例如/usr/local/bin (macOS) 或/usr/bin (Linux)。

【讨论】:

  • 太棒了。即使它涉及创建另一个脚本。我从您链接到的纯文本源复制并粘贴到一个文本文件中,并使用以下命令在 Cygwin 中运行它:fls.sh f *.png > pngs.txt 和宾果游戏:没有路径的 .png 文件列表。但实际上,ls 没有与 DOS 的“dir /b”开关相媲美的选项吗?我查看了 ls' --help 输出的内容,至少那里没有任何内容。
  • @AlexHall:谢谢; tl;博士:试试-1(第一名); ls 实际上默认为“裸”输出,即仅文件名,但是当输出到终端时使用基于列的布局(每行多个文件名)。要为每个输出行获取一个文件名(这是 dir /b 所做的,如果有记忆的话),请使用 -1 选项,它实际上是在 stdout 连接到终端时隐式打开的,例如就像发送到管道或输出文件一样。
【解决方案5】:

“find '-maxdepth'” 不适用于我的旧版本 bash,因此我使用:

对于 f in $(ls) ;如果 [ -f $f ] ;然后回显 $f ;菲;完成

【讨论】:

  • for f in $(ls) 的使用是双重错误的。您可以使用 for f in * 解决此问题,但它会中断,因为您没有正确引用 echo 的参数。
【解决方案6】:
{ find . -maxdepth 1 -type f | xargs ls -1t | less; }

添加了xargs 以使其正常工作,并使用-1 而不是-l 仅显示文件名而不显示其他ls 信息

【讨论】:

  • 这有一些优点,因为它强制按时间排序,尽管使用find -printf0 '...' | sort -z 可以说是不那么笨拙的方法
【解决方案7】:
ls -p | grep -v /

ls -p 让您在文件夹名称之后显示 /,它充当您删除的标签。

【讨论】:

  • 很高兴看到除find 之外还使用ls 的示例,因为后者返回相对路径而前者仅返回文件名。为工作使用正确的工具。
【解决方案8】:

查找文件:ls -l /home | grep "^-" | tr -s ' ' |剪切 -d ' ' -f 9

查找目录:ls -l /home | grep "^d" | tr -s ' ' |剪切 -d ' ' -f 9

查找链接:ls -l /home | grep "^l" | tr -s ' ' |剪切 -d ' ' -f 9

tr -s ' ' 将输出转换为以空格分隔的文件 cut 命令表示分隔符是一个空格,并返回第 9 个字段(始终是文件名/目录名/链接名)。

我一直用这个!

【讨论】:

  • 哇!如果文件名确实包含空格怎么办?
  • 使用“9-”从第 9 个字段开始获取所有内容。链接也受此影响,因为它们将位于第 9 个字段之后。
【解决方案9】:

列出某个目录的内容,不包括子目录

我喜欢使用ls 选项,例如:

  • -l 使用长列表格式
  • -t 按修改时间排序,最新优先
  • -r 排序时倒序
  • -F--classify 将指示符(*/=>@| 之一)附加到条目
  • -h--human-readable 带 -l 和 -s,打印尺寸如 1K 234M 2G 等...

有时--color 和所有其他人。 (见ls --help

列出除文件夹以外的所有内容

这将显示文件、符号链接、设备、管道、套接字等。

所以

find /some/path -maxdepth 1 ! -type d

可以很容易地按日期排序:

find /some/path -maxdepth 1 ! -type d -exec ls -hltrF {} +

仅列出文件

find /some/path -maxdepth 1 -type f

按大小排序:

find /some/path -maxdepth 1 -type f -exec ls -lSF --color {} +

防止列出隐藏条目

要不显示名称以点开头的隐藏条目,您可以添加! -name '.*'

find /some/path -maxdepth 1 ! -type d ! -name '.*' -exec ls -hltrF {} +

然后

您可以将/some/path 替换为. 以列出当前目录.. 以列出父目录

【讨论】:

    【解决方案10】:

    不客气!

    ls -l | grep '^-'
    

    仅查找名称,通过管道传递到 cutawk

    ls -l | grep '^-' | awk '{print $9}'
    
    ls -l | grep '^-' | cut -d " " -f 13
    

    【讨论】:

      【解决方案11】:

      您可以选择以下方法之一:

      echo *.* | cut -d ' ' -f 1- --output-delimiter=$'\n'
      echo *.* | tr ' ' '\n'
      echo *.* | sed 's/\s\+/\n/g'
      ls -Ap | sort | grep -v /   
      

      【讨论】: