Формат вывода для ls

Я удалил свой старый.oh -мой -zsh-файл, который находился в home/username/.oh-my-zshзатем установил его снова, запустив sh -c "$(curl -fsSL https://raw.github.com/robbyrussell/oh-my-zsh/master/tools/install.sh)"И проблема была решена.

1
18.11.2020, 18:22
1 ответ

git ls-tree -r --name-only, кажется, рекурсивно перечисляет все файлы, включая скрытые, но исключая файлы типа каталог , отсортированные по имени с использованием strcmp()в качестве функции сравнения сортировки.

Таким образом, чтобы получить что-то похожее на список содержимого каталога, а не список файлов в ревизии репозитория git, в zshвы можете сделать:

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

То есть:

  • LC_ALL=Cустановлен только для printдля его -oдля сортировки по значению байта (вместо порядка сортировки локали)
  • print -orC1:print, oприказ, rав на1Cколонке.
  • **/*:рекурсивная подстановка
  • (NDoN^-/)квалификатор сортировки, включая Nullglob (для расширения до нуля при отсутствии файла ), Dotglob (для включения скрытых файлов ), oNдля Not oраспорядился так, как printприкажет им в любом случае. ^-/исключает файлы типа каталог (, определенный после разрешения символической ссылки ).

С инструментами 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^-/)

(так как это порядок по умолчанию для глобусов ).

Или с GNUtools:

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"). Чтобы сделать что-то подобное, вы можете использовать GNU ls --quoting-style=c-maybeв локали C:

.

zshс GNUls:

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 --

Обратите внимание, что 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 в вашей локали )).

2
18.03.2021, 22:48

Теги

Похожие вопросы