
В Linux есть ли способсортировать ls
вывод по пользователям? Я пытаюсь добиться чего-то вроде этого:
пользователь_а файл1
пользователь_а файл2
пользователь_б другой_файл_пользователь_
с этот_файл_пользователь_
с этот_файл_пользователь_
г файл3
Я знаю, что такой список также будет содержать размер файла, разрешения и т. д. – меня больше всего волнует сортировка по пользователям. Было бы очень удобно, не правда ли?
Пока что я нашел ls -l | sort -k 3
сортировку по третьему столбцу, который [если используется ls -l
] содержит владельца файла [таким образом sort -k 4
сортируется по группе].
НОчто делать, если владелец файла не в третьей строке? Есть ли другой способдостичь этого, независимо от номера столбца?
Обновлять: Я забыл упомянуть об этомЯ работаю в BASHи постарайтесь придерживаться этого в течение некоторого времени, чтобы ситуация не стала еще более сложной.
решение1
Определить, в каком столбце находится имя владельца, из одного ls -l
вывода, не зная, что есть что, невозможно. Вы можете попытаться сопоставить записи в каждом столбце с passwd
файлом, но нет гарантии, что вы не сопоставите столбец группы или столбец имени файла, оба из которых могут содержать только имена, которые вы найдете в /etc/passwd
.
Если вы хотите использовать ls
, вы можете запустить программу дважды, один раз как ls -l
и один раз как ls -g
. Последний удаляет владельца, поэтому, сопоставляя строки на основе другой информации, вы сможете определить имя владельца без спецификации. Однако это не то упражнение, которое я бы с удовольствием проделал в скрипте оболочки bash.
решение2
С помощью zsh
можно определить порядок сортировки и использовать его в квалификаторах подстановки, например:
zmodload zsh/stat
uid() zstat -A REPLY +uid -- $REPLY
... *(no+uid)
( n
для числового порядка, o
длязаказ, +uid
чтобы упорядочить с uid
функцией). Идея состоит в том, чтобы иметь функцию, которая принимает имя файла $REPLY
и возвращает что-то, $REPLY
что zsh
сортирует по.
Так, например, с GNU ls
:
ls -ldU -- *(no+uid)
При использовании только инструментов GNU эквивалент будет выглядеть примерно так:
find . ! -name . -prune -printf '%U\t%p\0' |
sort -zn |
tr '\0\n' '\n\0' |
cut -f2- |
tr '\0\n' '\n\0' |
xargs -r0 ls -ldU
решение3
Не анализироватьls
: использоватьstat
stat -c "%U %n" -- * | sort
решение4
1) Определите, какой столбец имеет название:
myls='ls -al'
echo '+' > /tmp/MYOWNFILE.$$ #so file will be of size 2, "+" and newline.
zeuser=$( $myls /tmp/MYOWNFILE.$$ | awk -v myname=$(whoami) '{ for (field=1;field<=NF;field++) { if ($field == myname) { print field ; break } } }' )
zesize=$( $myls /tmp/MYOWNFILE.$$ | awk '{ for (field=1;field<=NF;field++) { if ($field == 2) { print field ; break } } }' )
zename=$( $myls /tmp/MYOWNFILE.$$ | awk -v filename=/tmp/MYOWNFILE.$$ '{ for (field=1;field<=NF;field++) { if ($field == filename) { print field ; break } } }' )
rm /tmp/MYOWNFILE.$$
Он помещает в переменную zeuser столбец, показывающий имя пользователя.
Я также определяю zesize=столбец, содержащий размер, и zename=столбец, содержащий имя файла.
Я поместлю команду ls в переменную, чтобы строки, определяющие столбец, использовали фактическую команду, которая будет использоваться позже (на случай, если вы измените ее, и это изменит перечисленные столбцы).
2) используйте sort для сортировки по этому столбцу:
$myls | sort -k${zeuser},${zeuser} #sort ONLY on column of usernames (see last example for bad alternative)
$myls | sort -k${zeuser},${zeuser} -k${zename},${zename} #sort on user, and then on filename
$myls | sort -k${zeuser},${zeuser} -k${zesize},${zesize}nr #sort on user,
# and then on size
#modifiers: 'n'=order Numerically (and not alphabetically),
# 'r'=Reverse order
$myls | sort -k${zeuser} #sort STARTING FROM user column, which is probably not what you want!
#indeed the next column is probably the group, then the size...
#It will be sorting in a not so usefull way (especially as the
# size will be sorted alphabetically instead of numerically)