Я хотел бы найти файлы, для которых у пользователя и других пользователей одинаковые разрешения. Я пробовал ls -l
и egrep
, но я не знаю, как сказать, что позиция 234 будет такой же, как позиция 567.
Заранее спасибо.
Обычно я не одобряю синтаксический анализ ls
, но здесь:
ls -l | sed -En '/^.(...)...\1/p'
stat
решение:
stat --format '%a %n' * | grep -E '^([0-9])\1'
или для используйте в скрипте с нулевым разделителем, получите только имена файлов:
stat --printf '%a\t%n\0' * | grep -Ez '^([0-9])\1' | cut -z -f2-
Примечание: ваш вопрос неясен, хотите ли вы найти файлы с теми же разрешениями пользователя и группы или с теми же разрешениями пользователя и других . Основываясь на вашем упоминании позиций 234 и 567 в строке режима, я предполагаю здесь первое - хотя те же методы могут быть легко адаптированы ко второму.
Если вы хотите найти файлы, у которых u ser, g roup и o thers ( ugo
) права все одинаковы, что довольно просто с помощью find
команда:
find . -type f \( -perm 000 -o -perm 111 -o -perm 222 -o -perm 333 -o -perm 444 -o -perm 555 -o -perm 666 -o -perm 777 \)
К сожалению, сделать то же самое для ug
намного сложнее - вам нужно будет проверить все 8 возможных o
байтов для каждой пары равных ug
байт. Однако вы можете автоматизировать это, используя расширение скобок bash для создания массива тестов -perm
:
perms=( $(printf -- '-o -perm %s\n' {00..77..11}{0..7}) )
затем
find . -type f \( -false "${perms[@]}" \)
Вероятно, лучший подход - использовать что-то, что может работать с битами режима арифметически - например через функцию perl stat
:
find . -type f -exec perl -le '
foreach (@ARGV) {print $_ unless (((stat)[2] & 00070) << 3 ^ (stat)[2]) & 00700}
' {} +
, которая извлекает биты группового и пользовательского режима и выполняет XOR - результат равен нулю (false), если они совпадают.
Если вы настроены на это путем анализа текстового представления файлового режима,немного более надежный способ, чем анализ вывода ls
, может выглядеть примерно так:
find . -type f -printf '%m\t%p\0' |
gawk -v RS='\0' 'match($1,/([0-7])([0-7])/,m) && m[2] == m[1] {print $2}'
(вы можете использовать простой .
вместо [0-7]
] в регулярном выражении, но я чувствую, что последнее делает намерение более ясным).