6

У меня есть клиент с деревом каталогов, у которого есть несколько каталогов высокого уровня, которые мне нужны на моей локальной машине для разработки. Я редко смотрю на них, если что-то не получается.

Я пометил "неинтересные" меткой серого цвета, а те, которые я использую ежедневно, меткой зеленого цвета в Finder. Это прекрасно работает в тех редких случаях, когда я использую Finder.

Вместо этого я использую Terminal.app, хотя я не против других эмуляторов терминала, если они быстрые и надежные. При использовании ls, даже с флагами @ и G, у меня нет полезной информации, которую я могу использовать, чтобы снять акцент с неинтересных записей каталога. (Если бы я мог передать ls через простой скрипт awk, чтобы применить раскраску, я бы с этим согласился.)

Я знаю, что могу использовать osascript для получения этого атрибута, а затем украсить вывод файла, но это, вероятно, приведет к самой медленной реализации ls со времен Unicos. Я также знаю, что могу изменить цвета по умолчанию с помощью ls, но это не совсем соответствует тому уровню, который мне нужен.

Есть ли простой, быстрый инструмент, который уже существует, который будет окрашивать вывод ls на основе цветов меток Finder, а затем возвращаться к $ LSCOLORS? Или это мой следующий проект на github? :-)

Спасибо!

2 ответа2

15

Информация о цвете доступна в com.apple.FinderInfo .

$ xattr -p com.apple.FinderInfo filename
00 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

Первая строка, десятый байт, биты 3-1 (т.е. с двоичными значениями 2, 4 и 8). Пример вывода для красного файла без других установленных значений.

Если атрибут недоступен или полубайт равен 0 , он бесцветный.

Возможные значения в порядке контекстного меню слева направо:0 (бесцветный), C (красный), E , A , 4 , 8 , 6 , 2 (серый).

Не забудьте проверить возможные 1 значения для этого последнего бита, т. Е. 3 также будет серым + некоторый другой атрибут.


Одним из возможных решений будет следующее:

Определите функцию ls в ~/.bash_profile которая делает что-то немного другое, если не заданы параметры:

function ls {
        if [ "$#" = "0" ] ; then
                find . -maxdepth 1 -exec ~/Library/Scripts/colorize.sh '{}' \;
        else
                $( which ls ) $@
        fi
}       

colorize.sh может выглядеть следующим образом, вызывая скрипт Python и печатая имя файла в зависимости от его вывода:

#!/bin/bash

filename=$1

if [ ! -e "$filename" ] ; then
    exit
fi

filename="$( basename "$filename" )"

attrs=( $( $( dirname $0 )/attrs.py "$filename" | cut -f2 ) )

hidden=${attrs[0]}

if [ "$hidden" = "True" ] ; then
    exit
fi

color=${attrs[1]}

case "$color" in
    "none" )
        format="setab 8"
        ;;
    "red" )
        format="setab 1"
        ;;
    "orange" )
        format="setab 1"
        ;;
    "yellow" )
        format="setab 3"
        ;;
    "green" )
        format="setab 2"
        ;;
    "blue" )
        format="setab 4"
        ;;
    "purple" )
        format="setab 5"
        ;;
    "gray" )
        format="setab 7"
        ;;
esac

echo "$( tput $format )$filename$( tput sgr0 )"

И attrs.py , который извлекает соответствующие атрибуты файла, в том же каталоге:

#!/usr/bin/env python

from sys import argv, exit
from xattr import xattr
from struct import unpack

if len(argv) < 2:
    print('Missing filename argument!')
    exit(1)

attrs = xattr(argv[1])

try:
    finder_attrs= attrs[u'com.apple.FinderInfo']

    flags = unpack(32*'B', finder_attrs)

    hidden = flags[8] & 64 == 64
    color = flags[9] >> 1 & 7
except:
    hidden = False
    color = 0

colornames = { 0: 'none', 1: 'gray', 2 : 'green', 3 : 'purple', 4 : 'blue', 5 : 'yellow', 6 : 'red', 7 : 'orange' }

print 'hidden:\t', hidden
print 'color:\t', colornames[color]

У меня не было достаточно большого выбора подходящего цвета, поэтому красный и оранжевый цвета напечатаны красным.

Я добавил hidden атрибут здесь, так как меня интересует эта часть изменения вывода ls . Просто удалите if заявление , если вы не хотите.

1

Спасибо @DanielBeck за его подробный ответ.

Вот очень быстрое и грязное решение, полезное для быстрой проверки метки некоторого файла в ssh:

#!/bin/bash

color_08=$'\e[44;30m' #blue
color_02=$'\e[47;30m' #gray
color_04=$'\e[42;30m' #green
color_0E=$'\e[46;30m' #orange/cyan
color_06=$'\e[45;30m' #purple
color_0C=$'\e[41;30m' #red
color_0A=$'\e[43;30m' #yellow
color_00=$'\e[m'
end=$'\e[K\e[m'

for f in *; do
    x=$(xattr -p com.apple.FinderInfo "$f" 2>/dev/null)
    x=${x:27:2}
    x=color_${x:-00}
    echo "${!x}$f$end"
done

Предупреждение: не используйте это в какой-либо профессиональной форме или форме, и не используйте его в любом файле, предоставленном кем-то другим, потому что он использует косвенное обращение с оболочкой, которое так же плохо, как и eval.

Кроме того, цвета были выбраны для моей конкретной цветовой схемы (Solarized Light). Возможно, вам придется настроить escape-последовательности в соответствии с вашей схемой.

Вот тестовая папка:

тест фолдель

А вот как это выглядит с моим скриптом:

вывод сценария

Оранжевый становится голубым, потому что это то, что обеспечивает терминал.

И да, это 2016, и им придется вырвать OS X 10.8 из моих холодных, мертвых пальцев :-)

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .