如何在 Linux 中为每个输出行列出一个文件名?

Posted

技术标签:

【中文标题】如何在 Linux 中为每个输出行列出一个文件名?【英文标题】:How do I list one filename per output line in Linux? 【发布时间】:2011-04-22 15:01:52 【问题描述】:

我正在使用ls -a 命令获取目录中的文件名,但输出在一行中。

像这样:

.  ..  .bash_history  .ssh  updater_error_log.txt

我需要一个内置的替代方法来获取文件名,每个文件名都在一个新行上,如下所示:

.  
..  
.bash_history  
.ssh  
updater_error_log.txt

【问题讨论】:

ls 旨在显示供人类消费的列表。如果您将 ls 用于任何其他目的(例如,获取要迭代的脚本中的文件列表),那么您肯定使用了错误的工具。 @juliano - 它实际上是由 python 脚本使用的。为什么你称它为错误的工具? @fixxer 当您将ls 传送到python 时,ls 将按照我在回答中的说明每行输出一个文件。 @fixxxer:那你确实是用错了。它格式化列表以在用户终端中输出。它可能会替换文件名中的特殊字符,它可能会省略具有特殊含义的字符,等等......换句话说,ls formats 给用户一个列表。您需要未格式化的文件名。您没有使用 python 'glob' 模块的任何特殊原因? docs.python.org/library/glob.html还有'fnmatch'、'dircache'等。 @fixxer 你真的让ls输出到python并观察到python中的单行输出吗? 【参考方案1】:

使用-1 选项(注意这是“一个”数字,而不是小写字母“L”),如下所示:

ls -1a

不过,首先,请确保您的 ls 支持 -1。 GNU coreutils(安装在标准 Linux 系统上)和 Solaris 可以;但如果有疑问,请使用man lsls --help 或查看文档。例如:

$ man ls
...
       -1     list one file per line.  Avoid '\n' with -q or -b

【讨论】:

+1 我不知道 -1(-l 是(不是一个))它显示在手册页中,但我一直在阅读它:) @slashmais - 啊,好点 - 容易出错。我在答案中澄清了。 @dty:对于 GNU,您可以在 ls --help 输出中记录此内容...始终安装 ;-) 在 Google 上搜索 linux ls one file per line,这是最热门的文章。无法相信所选择的答案是多么冗长,或者这个答案的投票数比通过管道传递给 cat 的答案要少。 ls -1ftw. ls 在输出未连接到终端时默认为 -1 行为。【参考方案2】:

是的,您可以轻松地让ls 每行输出一个文件名:

ls -a | cat

解释:命令ls 感知输出是到终端还是到文件或管道,并进行相应调整。

因此,如果您将ls -a 传递给 python,它应该可以在没有任何特殊措施的情况下工作。

【讨论】:

哇,这太棒了。优于公认答案的优势 - 这个实际上适用于 android / adb shell - 其中ls 只是一些精简版本,因此不支持-1 您如何避免在输出中显示...“文件”? @matanster:这取决于,你想看点文件吗?如果没有,只需删除 -a 选项。【参考方案3】:

Ls 专为人类消费而设计,you should not parse its output。

在 shell 脚本中,在少数情况下,解析 ls 的输出确实是实现预期效果的最简单方法。由于 ls 可能会破坏文件名中的非 ASCII 字符和控制字符,因此这些情况是不需要从 ls 获取文件名的情况的子集。

在 python 中,绝对没有理由调用ls。 Python 内置了 ls 的所有功能。使用os.listdir 列出目录的内容,使用os.statos 获取文件元数据。 os 模块中的其他功能也可能与您的问题相关。


如果您通过 ssh 访问远程文件,列出文件名的一种相当可靠的方法是通过 sftp:

echo ls -1 | sftp remote-site:dir

每行打印一个文件名,与ls 实用程序不同,sftp 不会破坏不可打印的字符。您仍然无法可靠地列出文件名包含换行符的目录,但这种情况很少发生(请记住,这是一个潜在的安全问题,而不是可用性问题)。

在python中(注意shell元字符必须在remote_dir中转义):

command_line = "echo ls -1 | sftp " + remote_site + ":" + remote_dir
remote_files = os.popen(command_line).read().split("\n")

对于更复杂的交互,在文档中查找 sftp 的批处理模式。

在某些系统(Linux、Mac OS X,可能还有其他一些 unice,但绝对不是 Windows)上,另一种方法是使用 sshfs 通过 ssh 挂载远程文件系统,然后在本地工作。

【讨论】:

我通过 SSH 连接到远程机器。我发现无法在远程机器上单行执行 os.listdir 之类的 python 函数。因此,这个问题。我不想编写一个简单列出文件的脚本。有没有其他方法可以解决这个问题? @fixxxer:ssh 确实改变了这种情况,这是您在原始问题中应该提到的那种事情!我认为 sftp 适合您的用例。 我很抱歉造成混乱。有没有办法我也可以在“命令行”中插入密码? @fixxxer:我不知道,ssh 的作者对以纯文本形式存储的密码不屑一顾,而且往往不会让这变得容易。你真的应该设置基于密钥的身份验证(网上有很多教程和superuser.com 上的问题)。【参考方案4】:

你可以使用ls -1

ls -l 也会做这项工作

【讨论】:

最佳答案已经提到了您所说的确切内容。该问题还特别指出不应使用ls -l【参考方案5】:

你也可以使用ls -w1

这允许设置列数。 来自 ls 的联机帮助页:

   -w, --width=COLS
          set output width to COLS.  0 means no limit

【讨论】:

【参考方案6】:
ls | tr "" "\n"

【讨论】:

【参考方案7】:

很简单,只要您的文件名不包含换行符:

find . -maxdepth 1

如果您将它传递到另一个命令中,您可能更喜欢用空字节而不是换行符分隔文件名,因为空字节不能出现在文件名中(但换行符可能):

find . -maxdepth 1 -print0

在终端上打印可能会显示为一行,因为通常不会打印空字节。某些程序可能需要特定选项来处理以空值分隔的输入,例如sort-z。您自己的脚本同样需要考虑这一点。

【讨论】:

以上是关于如何在 Linux 中为每个输出行列出一个文件名?的主要内容,如果未能解决你的问题,请参考以下文章

liunx 命令

linux如何显示一个目录下各子目录的文件个数

linux怎么查看一个文件夹的大小

Android:如何在一个查询中列出属于特定 RawContacts 帐户的所有数据行

如何列出 CSV 文件中的各个列?

如何在c ++中为每个嵌套循环打印新列中的输出?