Можно сделать это вручную с этой командой:
:hi Comment guifg=#ABCDEF
Где ABCDEF
соответствующий цветной шестнадцатеричный код.
Для создания этого постоянным необходимо будет добавить эти строки к Вашему ~/.vimrc
файл (использующий зеленый в качестве примера):
syntax on
:highlight Comment ctermfg=green
Если я правильно понимаю, вы хотите переместить файлы из текущего каталога и его подкаталогов рекурсивно в другой каталог, но только если команда файл
сообщает о них как о файлах «Microsoft Word». То есть вас интересуют файлы, для которых file "$ filename" | grep 'Microsoft Word'
производит некоторый вывод.
Самый простой способ - это спокойно относиться к делу и рассуждать последовательно. Если вам нужны файлы только в текущем каталоге, вы можете использовать цикл для
и шаблон подстановки:
for f in *.doc; do
if …
done
Какое условие? Мы хотим проверить, появляется ли Microsoft Word
в выводе файла «$ f»
. Я использую файл -
для защиты от файлов, имена которых начинаются с -
.
for f in *.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
…
fi
done
Все, что нам нужно сделать, это добавить команду для перемещения файлов.
for f in *.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
mv -- "$f" ../NewDirectory/
fi
done
Если вы хотите также искать файлы в подкаталогах, используйте шаблон **
Wilcdard для рекурсивного подстановки. В bash его нужно активировать с помощью shopt -s globstar
(в ksh93 вам нужно установить -o globstar
, а в zsh он работает из коробки; в других оболочках этого нет характерная черта). Помните, что bash ≤4.2 следует за символическими ссылками на каталоги.
for f in **/*.doc; do
if file -- "$f" | grep -s 'Microsoft Word'; then
mv -- "$f" ../NewDirectory/
fi
done
Обратите внимание, что все перемещенные файлы заканчиваются на ../ NewDirectory /
, подкаталоги не создаются. Если вы хотите воспроизвести дерево каталогов, вы можете использовать конструкции обработки строк для извлечения части каталога из имени файла и mkdir -p
для создания целевого каталога, если это необходимо.
for f in ./**/*.doc; do
if file "$f" | grep -s 'Microsoft Word'; then
d="${f%/*}"
mkdir -p ../NewDirectory/"$d"
mv "$f" ../NewDirectory/"$d"
fi
done
Вместо синтаксического анализа вывода файла
, который несколько хрупок, вы можете предпочесть синтаксический анализ file -i
, который печатает стандартизованные строки.
Ваш первый пример файла
не будет работать из-за несоответствующей одинарной кавычки, но я думаю вы уже обнаружили это из-за вашего второго примера.
Если вы сделаете:
find . -type f
, вы можете посмотреть результат. Это имена файлов. Если вы хотите выбрать что-то из этого вывода, используйте grep
напрямую
find . -type f | grep "Microsoft Word"
, который выполняет поиск по именам файлов, а не по содержимому перечисленных файлов. Это не совсем точно, поскольку в имени файла может быть новая строка, что делает вывод неполным, если имя файла с «Microsoft Word» содержит новую строку как часть имени.
Если вы это сделаете:
find . -type f -print0 | xargs -0 grep -lh "Microsoft Word"
часть xargs
фактически передает имена файлов в grep ( -print0
для find
и -0
for xargs
- обрабатывать имена файлов с символами новой строки).
Это ищет всю строку «Microsoft Word», а не только «Word» в файлах .
-lh
, указанный для grep
, перечисляет имена файлов, и может быть проблема с этим, поскольку новые строки в именах файлов печатаются нормально, вы должны продолжать использовать имена файлов с завершением NUL, также указав -Z. Если вы не укажете -l
, вы также получите совпадение содержимого строк, что сделает дальнейшую обработку (ваш mv
) невозможной.
Если вы хотите переместить все файлы в один каталог, часто проще использовать mv -t
вместо удаления с опцией xargs
' -I
(что позволяет вам поместить параметры xargs
, считываемые с его ввода, в другое место, чем конец строки по умолчанию, но это медленнее, поскольку mv вызывается один раз для каждого файла):
find . -type f -print0 | xargs -0 grep -lhZ "Microsoft Word" | xargs -0 mv -t ../NewDirectory/
все файлы где-то в текущем каталоге, с «Microsoft Word» в части их содержимого в NewDirectory
, который находится рядом с текущим каталогом. Обратите внимание, что ../ NewDirectory
должен существовать.