ls 的格式化输出

ls 的格式化输出

我正在寻找一种方法来列出文件夹中的内容并以此格式输出:

folder/file.txt

与 git 命令的输出类似:

git ls-tree -r --name-only

有什么建议么?

答案1

git ls-tree -r --name-only似乎递归地列出所有文件,包括隐藏文件,但不包括 type 的文件目录,按名称排序,用作strcmp()排序比较函数。

因此,要获得接近列出目录内容而不是存储库修订版中的文件列表的内容gitzsh您可以执行以下操作:

LC_ALL=C print -orC1 -- **/*(NDoN^-/)

那是:

  • LC_ALL=C仅设置为print-o字节值排序(而不是区域设置排序顺序)
  • print -orC1: printo订购了,r哦,在1 C专栏上。
  • **/*: 递归通配符
  • (NDoN^-/)排序限定符,包括Nullglob(没有文件时展开为空)、Dotglob(包括隐藏文件),oN用于Not oordered asprint将以任何方式对它们进行排序。^-/排除类型的文件目录(在符号链接解析后确定)。

使用 GNU 工具,您可以获得与以下内容等效的东西:

find . ! -xtype d -printf '%P\0' |
  LC_ALL=C sort -z |
  tr '\0' '\n'
  • ! -xtype d:排除目录和目录的符号链接。
  • -printf '%P\0'打印路径之内 .(即没有./前缀)NUL 分隔。
  • LC_ALL=C sort -z按字节值而不是区域设置排序规则对该列表进行排序。
  • tr '\0' '\n':将 NUL 转换为换行符,以便人类用户可以阅读列表(尽管我们不再知道每个文件名(可能由多行组成)在哪里开始和结束)。

要排除隐藏文件,请更改为:

LC_ALL=C print -orC1 -- **/*(NoN^-/)

如果您不介意使用排序顺序(例如lssort,但git ls-tree默认情况下不这样做)而不是strcmp()顺序,您可以简化它:

print -rC1 -- **/*(N^-/)

(因为这是 glob 的默认顺序)。

或者使用 GNU tools

LC_ALL=C find . -name '.?*' -prune -o ! -xtype d -printf '%P\0' |
  sort -z |
  tr '\0' '\n'

LC_ALL=C需要find它来.?*匹配全部隐藏文件,甚至那些包含在您的语言环境中不形成有效字符的字节值的文件。

git ls-tree但是,将包含非 ascii 字符(默认情况下core.quotePath可以按存储库设置的配置设置true)或控制字符或\"作为 C 样式字符串(例如"foo\"bar\nbaz")的文件名进行编码。要执行类似的操作,您可以ls --quoting-style=c-maybeC语言环境中使用 GNU:

zsh与 GNU ls

print -rNC1 -- **/*(N^-/) |
  LC_ALL=C xargs -r0 ls --quoting-style=c-maybe -1dU --

GNU 工具:

LC_ALL=C find . -name '.?*' -prune -o ! -xtype d -printf '%P\0' |
  sort -z |
  LC_ALL=C xargs -r0 ls --quoting-style=c-maybe -1dU --

请注意,输出一个名为as 的ls文件,而将其输出为.如果你真的关心,你总是可以将整个事情通过管道来获得相同的输出。\\git ls-tree"\\"sed -e '/^"/b' -e '/\\/!b' -e 's/\\/&&/g' -e 's/.*/"&"/'

zsh:q如果您在其 glob 限定符中使用修饰符,则可以为您提供不同的引用样式。一个带有git奇怪文件名的存储库的示例:

$ ls -AFq
''$'\351'  ''$'\n'  '"'  '\'   a  'a'$'\n''b'   B      é      .git/  'my dir'/
''$'\b'    ' '      "'"  '~'   A   b            dir/   .foo   link@
$ git ls-tree -r --name-only HEAD
"\b"
"\n"

"\""
'
.foo
A
B
"\\"
a
"a\nb"
b
link
my dir/file
~
"\303\251"
"\351"
$ print -rC1 -- **/*(N^-/:q)
\ 
\"
\'
\\
\~
$'\351'
$'\b'
$'\n'
a
A
a$'\n'b
b
B
é
link
my\ dir/file
$ LC_ALL=C find . -name '.?*' -prune -o ! -xtype d -printf '%P\0' |
pipe>   sort -z |
pipe pipe>   LC_ALL=C xargs -r0 ls --quoting-style=c-maybe -1dU --
"\351"
"\b"
"\n"

"\""
'
\
~
a
A
"a\nb"
b
B
"\303\251"
link
my dir/file

(请注意缺失.foo(尽管它在存储库中并由 列出git ls-tree),.git(不在存储库中,因为存储库只是git存储元数据的地方),文件编码的差异\和排序顺序的差异(特别是关于小写与大写, YMMV 在您自己的语言环境中))。

相关内容