Не для кого не секрет, что некоторые типичные действия на компьютере проще быстрее и эффективнее выполнить из-под командной строки нежели мышкой в GUI explorer(e).
Поэтому в этом тексте я хотел бы поделиться командами, которые мне очень часто помогают в повседневной работе.
То что я тут напишу этим обычно не делятся. Как правило у каждого разработчика есть свой потайной сheat-list полезных консольных команд для выполнения какой-либо работы.
Наверное этот текст также обидит чувства Windows пользователей, так как тут по сути предлагается использовать Unix(овые) утилиты в OS Windows. Многие пользователи Windows, которых я знаю религиозно презирают Linux и всё, что с этим связано. Предвижу что текст уйдет в глубокий минус.
Пользоваться Unix утилитами в OS Windows это тоже, что если бы американские солдаты во время своих зверств во Вьетнаме бросали бы свои винтовки M-16, а пользовались бы исключительно и только автоматами Калашникова. Однако, тем не менее, и такое было!
Но на самом деле нет ничего плохого в том что на Windows 10 запускать Unix утилиты. Это лишь подчёркивает тот факт, что хороший компьютер это, прежде всего, универсальный вычислитель.
Итак, Unix(овые) утилиты для командной строки можно с легкость отрабатывать и в операционной системе Windows, если установить GIT и открыть консоль GIT.
Также их можно установить из CygWin или MinGW.
Полезные команды в интерпретаторе Bash
26--На работе мне в мессенджер Junior программисты микроконтроллеров часто пишут личные сообщения типа:
В каком файле и папке лежит тело функции UsecToStr(...)?
Для этого есть очень простой шаблон на основе утилиты grep. Открываешь папку корня workspace репозитория и набираешь команду
grep -rn "UsecToStr(" | grep "\.c:"
Тут опция -r значит искать во всех папках, -n значит показывать в отчете номер строки на которой обнаружилась искомая подстрока. В общем, ступенчатый grep способен найти даже иголку в стоге сена!
Правда в том, что если у Вас локально на SSD/HDD диске есть Си-код и Вы знаете и умеете пользоваться утилитой grep, то Вам в принципе не нужна никакая другая документация для кода! Любую информацию Вы сможете извлечь при помощи grep запросов.
1--Показать абсолютный путь к утилите, например grep
where grep
2--Рекурсивно заменить слово old_word на new_word во всех файлах внутри директории.
grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'
Тут для grep -r означает, что искать внутри папок рекурсивно, -l означает показывать только пути к файлам. Для sed -i означает, что замена слова будет произведена прямо в этом же файле (in place), s означает что надо заменить первый токен на второй токен, флаг g заменяет все вхождения заменяемого токена.
Также бывает очень полезно сделать автоматическую замену предложения в конкретном файле. Это часто происходит из-за несовместимости между настройками IDE Eclipse в файле .cproject. Чинится это так.
sed -i -e 's/ARM family/Arm family (-mcpu)/g' .cproject
sed -i -e 's/"GNU Tools for ARM Embedded Processors"/"xPack GNU Arm Embedded GCC"/g' .cproject
Предположим у вас в организации запрещены многострочные комментарии /**/. Вы можете удалить суффиксы и заменить префиксы. Вот так
# удалить */
grep -rl '*/' . | xargs sed -i 's/\*\///g'
# заменить /* на //
grep -rl '/*' . | xargs sed -i 's/\/\*/\/\//g'
# заменить ///* на //**
grep -rl '///*' . | xargs sed -i 's/\/\/\/\*/\/\/\**/g'
32-- Рекурсивно in-place заменить все TAB отступы на 4 пробела. TAB (\t) в сорцах, зачастую, запрещены в 3 из 5 организациях
find . -type f -exec sed -i 's/\t/ /g' {} +
25--Во всех файлах в этой папке (включая вложенные папки с файлами) удалить все строки в которых есть ключевое слово KeyWord, начиная с данной директории
find . -type f -print0 | xargs -0 sed -i /KeyWord/d
Вообще с командой sed надо быть очень осторожным! Sed может тихо изменить там, где это не следует (например *.ewp настройки проекта в IAR), и потом не откроется проект в вашей любимой GUI-IDE. Как следствие Вы не сможете больше никогда собрать свой проект. И у Вас могут начаться из-за этого паника, судороги и конвульсии.
3-- Показать размер папок
du -a --max-depth=1 | sort -n
4-- Показать переменные окружения. Это очень частая команда для проверки системы перед сборкой.
env
5-- Найти все файлы с расширением .bak
find . -type f -name "*.bak"
6-- Удалить все файлы с расширением .bak
find . -type f -name "*.bak" -delete
7-- Открыть все *.mk файлы
for f in $(find . -name '*.mk' -not -name "sub"); do start Notepad++ $f; done
8-- Удалить строку 35 из файла file.doti
sed -i '35d' file.doti
9--Найти все директории с именем Drivers в данной папке
find . -name 'Drivers' -type d
10--Найти *.с и *.mk файлы в локальном GIT репозитории
git status | grep -e "\.mk" -e "\.[ch]" | grep -v "\.cmake" | grep -v "\.html"
11--Отсортировать процессы по потреблению RAM
tasklist | sort -k5
12--Узнать количество свободно места на диске
df -h
13--Показать размер папок
du -hs * | sort -hr
14--Установить переменную окружения в Bash
export var=some_value
В консоли Windows cmd переменные окружения устанавливаются так
set VAR_NAME=VAR_VALUE
15--Удалить папку со всем её содержимым.
rm -rf folder_to_delete
16--Отсортировать строки по конкретной колонке.
sort -nr -k6 -t'|' LoRaByteRatesTable.txt -o LoRaByteRatesTable_sorted.txt
17--Найти все файлы больше 10Mbyte.
find -type f -size +10M
18--Поиск файла по расширению *.s.
find . -name '*.s'
19-- Команда, которая ищет во всех файлах проекта места с упоминанием ключевого слова "LED", причем только в файлах board.h
grep -rn LED | grep board.h
Это команда приведена только для примера, что через консоль можно делать поиск поверх предыдущего поиска. Так называемый многоступенчатый поиск. Встроенному поиску из-под GUI-IDE такое даже и не снилось.
20--Показать состояния TCP соединений.
netstat -n -p TCP
Опция -n показать IP адрес и локальный порт, -p значит указать название протокола
31-- Удалить in-place рекурсивно во всех файлах все строки, которые содержат текст "param[out] None"
find . -type f -print0 | xargs -0 sed -i '/\param\[out\] None/d'
21-- Автоматически отсортировать строчки в конфиг файле по алфавиту и еще при этом удалить повторения.
sort.exe -u config.mk -o config.mk
Мега полезная команда так как после нее образуется минимальный diff в утилите WinMerge. Эту команду вообще надо прописать в скрипты сборки кода.
22--Показать все файлы с расширением *.mk в git репозитории
git status | grep "\.mk"
Вообще консольный git и grep это не иначе как неразрывные друзья! Можно также найти все файлы любого другого расширения. Выбрать то, что вы хотите зафиксировать и сделать очень прицельный и аккуратный коммит.
23--Типичная ситуация. Вы делаете git pull и получаете вот такую картинку.
Проблема это сообщение
error: The following untracked working tree files would be overwritten by merge:
Для того чтобы загрузить изменения из удаленного репозитория и продолжить работу надо переименовать папку nrf5340_dk_nortos_max98357a_m. И естественно это можно сделать из командной строки. Грубо говоря, не отходя от кассы.
mv source/projects/nrf5340_dk_nortos_max98357a_m/ source/projects/nrf5340_dk_nortos_max98357a_m_old7
И также надо переименовать файл flash_preconfig.mk из командной строки. Делает это команда mv
mv source/mcal/mcal_common/flash/flash_preconfig.mk source/mcal/mcal_common/flash/flash_preconfig_old.mk
Далее уже имея две папки (локальная и от удаленного репозитория) можно сравнить две версии в культовой утилите WinMerge и выбрать лучшее из обоих версий файлов для сборки очередной прошивки.
27-- Иной раз надо целиком скопировать одну папку в другую папку без лишних вопросов о подтверждении действий. Для этого существует Windows утилита robocopy
robocopy dir/source_dir dir/destination_dir /S
Тут /S означает копировать поддиректории за исключением пустых директорий
24-- Найти все папки в которых отсутствуют файлы с расширением *.gvi
comm -3 <(find . -type f -name ".gvi" -exec dirname {} ; |sort -u) <(find . -type d |sort -u)
Сначала строится список всех локальных директорий, которые содержат файлы *.gvi,
find . -type f -name ".gvi" -exec dirname {}
этот список всех локальных директорий, которые содержат файлы *.gvi сортируется.
find . -type f -name "*.gvi" -exec dirname {} ; |sort -u
Затем строится просто список всех локальных директорий
find . -type d
список всех локальных директорий тоже сортируется.
find . -type d |sort -u
После чего эти списки сравниваются и подавляются строчки фигурирующий в обоих файлах (comm -3). Остаются только строчки, которые показывают те папки в которых нет какого-либо специфического расширения.
Это очень удобная команда для самопроверки факта окончания работы по какому-либо программному компоненту. Например добавлению *.cmake файлов в кодовую базу
28-- Показать количество строк Си-кода во всей локальной кодовой базе
find . -name '*.[ch]' -type f -print0 | xargs -0 cat | wc -l
Это очень полезная команда для оценки масштаба репозитория с которым приходится работать. Например сейчас у меня репозиторий в котором лежит 8.7 миллионов строк кода.
29--Взять все файлы в этой папке и в каждом имени файла переименовать подстроку at24c02mtr на at24cxx
find . -type f -exec rename -v at24c02mtr at24cxx {} \;
Эта очень удобная команда, когда надо написать программный компонент по образу и подобию другого программного компонента. Сначала переименовываем названия файлов (find+rename)
а потом переименовывает ключевые слова в самих файлах (grep+sed)
grep -rl oldtext . | xargs sed -i 's/oldtext/newtext/g'
и "Вуаля"! Вся работа выполнена двумя строчками кода в командной строке!
30--Допустим у вас в компании есть code style и там есть ограничение на максимальную длину строки. Вот три способа как найти все файлы и строки внутри, где длинна строки больше, чем 100 символов
find . -type f -exec grep -En '.{120}' {} +
find . -type f -print | xargs grep -on '.\{102\}'
find . -type f -exec awk 'length($0) > 100 { print FILENAME, FNR}' {} +
33-- Сгенерировать *.wav файл с частотой 2 kHz и длительностью 3сек
ffmpeg -f lavfi -i "sine=frequency=2000:duration=3" test2kHz.wav
Вывод
Как видите, использование командной строки CLI позволяет снизить утомляемость от напряжения внимания и, как следствие, существенно повысить производительность работы за персональным компьютером PC.
Если говорить метафорично, то утилиты Unix - это как химическая посуда (пробирки, колбы, делительные воронки, мензурки, воронки, фильтры, капельницы, часовые стекла, стеклянные палочки), только применительно к данным (числам и тексту). Видимо авторы UNIX в 196х-197х были серьезно вдохновлены химией при разработке компьютерных консольных утилит. Согласитесь, что ну невозможно не заметить этих аналогий между UNIX утилитами и химической посудой.
Если Вы тоже знаете какие-либо простые элегантные и главное полезные консольные команды, то пишите их в комментариях. Не обязательно из bash можно и из cmd или вообще из powershell(а). Лишь бы эти команды умещались в одну строку.
Ссылки