我正在寻找一种方法来列出文件夹中的内容并以此格式输出:
folder/file.txt
与 git 命令的输出类似:
git ls-tree -r --name-only
有什么建议么?
答案1
git ls-tree -r --name-only
似乎递归地列出所有文件,包括隐藏文件,但不包括 type 的文件目录,按名称排序,用作strcmp()
排序比较函数。
因此,要获得接近列出目录内容而不是存储库修订版中的文件列表的内容git
,zsh
您可以执行以下操作:
LC_ALL=C print -orC1 -- **/*(NDoN^-/)
那是:
LC_ALL=C
仅设置为print
按-o
字节值排序(而不是区域设置排序顺序)print -orC1
:print
,o
订购了,r
哦,在1
C
专栏上。**/*
: 递归通配符(NDoN^-/)
排序限定符,包括N
ullglob(没有文件时展开为空)、D
otglob(包括隐藏文件),oN
用于N
oto
ordered 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^-/)
如果您不介意使用排序顺序(例如ls
或sort
,但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-maybe
在C
语言环境中使用 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 在您自己的语言环境中))。