Найти строки, которые начинаются с #define и заканчиваются на \

Я бы хотел эту команду:

date +%s | sha256sum | base64 | head -c 12
2
04.05.2017, 18:01
5 ответов

awk может выполнять синтаксический анализ и подсчет за одну операцию, при условии, что вы можете передать все нужные имена файлов, не превышая ARG_MAX:

awk '$1=="#define"&&/\\$/ {n[$2]++} END {for(i in n) print n[i],i}' *.[ch]

# this includes #define's that are indented with whitespace,
# which the C language allows. If you really want only #defines 
# that start exactly in column 1, use /^#define /&&/\\$/ 

# if you want the columns to line up change the print to something like
#   printf "%6d %s\n",x[i],i
1
27.01.2020, 22:18
sed '/#define/,\
        /^\(.*[^\]\)*$/N
        /\n\\/P;D'
-2
27.01.2020, 22:18

Большое спасибо. Я использовал предоставленные вами решения для создания своих нужд. :)

awk '/#define.*\/$/{cnt[$2]++}END{for(i in cnt)print i}' > macro_names

#!/usr/local/bin/bash -x
TotalCount=0
CurrFileTotalCount=0
#takes One $macro after other from macro_names.txt file
for macro in $(cat macro_names); 
do
    #Takes $files from the current path in a recursive manner 
    #<$(find . -type f -name "*.c" -o -name "*.h")
    for files in $(find . -type f -name "*.c" -o -name "*.h")
    do
        #Counts the number of times $macro is present in $files
         CurrFileTotalCount=$(grep -c $macro "${files}");
         #Adds the Current file count to $TotalCount
         TotalCount=$(($TotalCount+$CurrFileTotalCount));
         #print the $CurrFileTotalCount and $TotalCount PROPERLY
    done 
    #Expected to print how many times that $macro is present in the files -- BUT PRINTS $TotalCount AS 0
    echo $macro appears_3 TotalCount $TotalCount
    TotalCount=0;
done
0
27.01.2020, 22:18

Если в вашем файле есть такие строки:

#define MACRO_NAME DEFN_LINE1\

, тогда будут получены уникальные значения для MACRO_NAME:

cat yourCfile | grep '#define' | awk '{print $2}' | sort -u > macro_names

grep получает строки, содержащие '#define'

. ] awk обрабатывает каждую строку в строке как новое поле, используя пробел/пробелы в качестве разделителя полей по умолчанию. Итак, здесь мы просто используем awk для печати второго поля в «#define MACRO_NAME DEFN_LINE1\», которое является «MACRO_NAME».

sort -u > macro_names просто удаляет все дубликаты и выводит все в файл.

и чтобы просмотреть список имен макросов и найти, сколько строк содержат это имя макроса:

for macro in $(cat macro_names); do
count=$(cat yourCfile | grep $macro | wc -l);
echo $macro appears $count times
done

команда "wc" с флагом "-l" выводит количество строк, которые она получает из стандартного ввода.

0
27.01.2020, 22:18

Использование exuberant ctags:

$ ectags --c-kinds=d *.[ch]

ectags является расширенной версией ctags и etags используется для создания «файла тегов», который может использоваться такими редакторами, как Vi/Vim или Emacs, для удобной навигации по исходному коду. Он знает о правилах грамматики C, поэтому он может анализировать код C для вас (так что вам не нужно беспокоиться о регулярных выражениях).

С помощью --c-kinds=d мы указываем ectags заботиться только о #define строках кода C.

Теперь у вас есть файл с именем tags в текущем каталоге со следующим типом содержимого:

DEVELOPER       bayes.h 225;"   d
DIFFERENT       bayes.h 227;"   d
DIR_MIN bayes.h 338;"   d
DNA     bayes.h 242;"   d
DOLLAR  bayes.h 309;"   d
DOLLO   bayes.h 276;"   d
DOWN    bayes.h 215;"   d

То есть каждая строка (за исключением нескольких строк заголовка) идентифицирует имя макроса, исходный файл, в котором он был найден, и номер строки. Если макрос определен в нескольких файлах, он будет указан один раз для каждого вхождения. Последний d — это индикатор типа тегов (это все #defines).

Если вы просто хотите подсчитать, сколько раз был определен каждый макрос:

$ cut -f 1 tags | uniq -c
2
27.01.2020, 22:18

Теги

Похожие вопросы