Вы можете использовать $LS_COLORS
для этого. Если ваша версия ls
поддерживает указание цветов с помощью этой переменной, вы можете определить вывод для каждого типа файла. Это встроенное поведение и очень настраиваемый. Поэтому я создал несколько файлов для демонстрации, например:
for f in 9 8 7 6 5 4 3 2 1
do touch "${f}file" &&
ln -s ./"${f}file" ./"${f}filelink"
done
Так что теперь я сделаю:
LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \
ls -1 --color=always | cat
###OUTPUT###
1file
HERE_THERE_BE_A_LINK>>1filelink@
2file
HERE_THERE_BE_A_LINK>>2filelink@
3file
...
HERE_THERE_BE_A_LINK>>8filelink@
9file
...
И нули тоже есть ...
LS_COLORS='lc=:rc=:ec=:ln=\n\n\0HERE_THERE_BE_A_LINK>>\0:' \
ls -1 --color=always | sed -n l
1file$
$
$
\000HERE_THERE_BE_A_LINK>>\0001filelink@$
2file$
$
$
\000HERE_THERE_BE_A_LINK>>\0002filelink@$
3file$
...
Вы можете указать для всех или любых типов файлов. Делая это только для одного типа файла, вы, возможно, не захотите, поскольку в ls
него включены некоторые значения компиляции по умолчанию для экранирования терминала. Вы бы гораздо лучше обращались к API как к единому интерфейсу. Вот простой маленький способ синтаксического анализа и назначения текущих dircolors
настроек среды по умолчанию:
LS_COLORS='rs=:no=//:lc=:rc=:ec=//:'$(
set -- di fi ln mh pi so do bd cd or su sg ca tw ow st ex
for fc do printf %s "$fc=/$fc//:"
done) ls -l --color=always | cat
Его вывод в мой домашний каталог выглядит так:
total 884
///-rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 /fi//1/
//drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 /di//Desktop//
//-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 /fi//Terminology.log/
//-rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 /fi//new
file/
//lrwxrwxrwx 1 mikeserv mikeserv 10 Jul 11 04:18 /ln//new
file
link/ -> /fi//./new
file/
//-rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 /ex//script.sh/*
//-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 /fi//shot-2014-06-22_17-10-16.jpg/
//-rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 /fi//target.txt/
Вы можете запустить это cat -A
тоже, и единственное отличие, с которым вы столкнетесь, это то, что вы увидите $
новые строки - в ls --color=always
этой конфигурации нет непечатаемых символов - только то, что вы видите здесь.
ls
вставляет свой экранированный терминал по умолчанию следующим образом:
${lc}${type_code}${rc}FILENAME${lc}${rs}${rc}
... где значения по умолчанию для $lc
(слева от кода) , $rc
(справа от кода) и $rs
(сброса) :
\033 - ESCAPE
m - END ESCAPE
0 - reset
...соответственно. ${type_code}
используется для обозначения различных fi
(обычный файл - по умолчанию не установлено) , di
(каталог) , ln
(ссылка) и любого другого типа файла, который я знаю. Существует также $no
(нормальный), который также по умолчанию не установлен и который представлен здесь //
в начале каждой строки. Мой простой маленький IFS=:
блок работает, просто вставляя имя для каждого конфигурируемого в качестве его собственного значения и добавляя косую черту или два - хотя \0
байты NUL тоже подойдут.
По умолчанию ls
также будет вставлен один, $rs
непосредственно предшествующий его первому выводу $lc
- но это не точно представлено здесь. В этом случае я указал $ec
(код конца), который заменяет во $rs
всех случаях - когда он указан, вы не получаете лишних $rs
между $no
и, ${type_code}
как в противном случае - он представляет только сразу после имени файла и один раз в начале вывода - как вы можете видеть в одной дополнительной косой черте в начале первой строки.
Вот фрагмент из моего собственного $LS_COLORS
printf %s "$LS_COLORS"
rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:\
so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:\
or=40;31;01:su=37;41:sg=30;43:ca=30;41:\
tw=30;42:ow=34;42:st=37;44:ex=01;32:\
*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:...
И, по правде говоря, мой маленький взлом оболочки, вероятно, слишком сложен - есть широко доступный интерфейс для назначения этих значений. Попробуйте dircolors -p
в вашем кли и info dircolors
для получения дополнительной информации об этом.
Вы можете заключить имена файлов в произвольные строки. Вы можете закомментировать их, если хотите. Вы можете указать аналогичное поведение только на основе расширения файла. Там действительно не так много, вы не можете указать таким образом.
Теперь я не просто все это придумываю - я узнал об этом после того , как случайно наткнулся на исходный код .
С этой конкретной конфигурацией ls
будет излучать:
$no
- один раз за запись в начале каждой записи
${type_code}
- один раз непосредственно перед каждым именем файла, чтобы включить аббревиатуру типа файла и всегда находиться в той же строке, что и 7 полей с пробелами после $no
или сразу после ->
обозначения цели символической ссылки.
$ec
- один раз непосредственно перед самой первой строкой, а затем только один раз сразу после каждого имени файла.
Все остальные значения пусты.
Далее следует нулевой разделитель ls
, и на этот раз я буду использовать cat -A
, хотя без него это выглядело бы так же, как в предыдущем примере:
LS_COLORS='rs=:no=\0//:lc=:rc=:ec=\0//:'$(
set -- di fi ln mh pi so do bd cd or su sg ca tw ow st ex
for fc do printf %s "$fc=/$fc//\0:"
done) ls -l --color=always | cat -A
total 884$
^@//^@//-rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 /fi//^@1^@//$
^@//drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 /di//^@Desktop^@///$
^@//-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 /fi//^@Terminology.log^@//$
^@//-rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 /fi//^@new$
file^@//$
^@//lrwxrwxrwx 1 mikeserv mikeserv 10 Jul 11 04:18 /ln//^@new$
file$
link^@// -> /fi//^@./new$
file^@//$
^@//-rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 /ex//^@script.sh^@//*$
^@//-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 /fi//^@shot-2014-06-22_17-10-16.jpg^@//$
^@//-rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 /fi//^@target.txt^@//$
И поэтому, чтобы надежно удалить все символические ссылки из -l
списка ong, как этот, вы можете сделать простое изменение:
LS_COLORS='rs=:no=//:lc=:rc=:ec=/ :'$(
set -- di fi mh pi so do bd cd or su sg ca tw ow st ex
for fc do printf %s "$fc=$fc/:"
done)ln=///: ls -l --color=always | sed ':ln
\|///|{N;\|\n//|!bln};s|.*//||'
Мои результаты после запуска выглядят так ...
total 884
-rw-r--r-- 1 mikeserv mikeserv 793 Jul 9 11:23 fi/1/
drwxr-xr-x 1 mikeserv mikeserv 574 Jun 24 16:50 di/Desktop/ /
-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 fi/Terminology.log/
-rw-r--r-- 1 mikeserv mikeserv 0 Jul 6 11:24 fi/new
file/
-rwxr-xr-x 1 mikeserv mikeserv 190 Jun 22 11:26 ex/script.sh/ *
-rw-r--r-- 1 mikeserv mikeserv 433568 Jun 22 17:10 fi/shot-2014-06-22_17-10-16.jpg/
-rw-r--r-- 1 mikeserv mikeserv 68 Jun 17 19:59 fi/target.txt/
Используя некоторую команду, подобную той, что я делаю выше:
LSCOLORS=...$(...)fc1=///:fc2=///: ls ... | sed ...
... (где fc1
и fc2
являются типами файлов, перечисленными после set --
в подоболочке) должен служить для надежного удаления любых комбинаций типов файлов, которые вы можете захотеть ls
выводить независимо от любых символов, которые могут содержать имена файлов.