Как перечислить все повторяющиеся строки в нескольких скриптах Python - PullRequest
0 голосов
/ 18 мая 2018

У меня есть много сценариев Python в моем проекте, и некоторые из них содержат вложения / списки / наборы, такие как:

hi.py

hi_dict = {
    'de': 'hallo',
    'en': 'hello',
}

Но некоторые файлысодержат похожие или даже одинаковые слова:

maintenace / hello.py

class hello(superclass):
    hello_dict = {
        'en': 'hello',
        'fa': 'سلام',
    }

Я хотел бы объединить одинаковые целевые диктанты в один (который можно импортировать издругие случаи).Но сначала мне нужно найти такие слова.

Как мне найти во всех моих скриптах Python (используя терминальные команды Python или Unix) дубликаты строк (в данном случае 'en': 'hello',), но исключить начальные /конечные пробелы и пустые строки?

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

Примечание: я использую git, поэтому могу повредить скрипты, чтобы каким-либо образом получить результат, а затем восстановить их из прошлоголегко коммитить.

Решением этой проблемы также может быть поиск дублированного кода, который я мог бы объединить и уменьшить сложность кода, поэтому определенно это может быть применимо также для повышения оценки кода или для ускорения всей инфраструктуры.

Ответы [ 2 ]

0 голосов
/ 20 мая 2018

Когда часть dict всегда начинается со строки, заканчивающейся dict = {, вы можете сначала выбрать определения dict (возможно, изменить поиск).
В части dict вас интересуют только строки с :, так что напечатайте их.
Удалите форматирование, поэтому удалите пробелы и символы табуляции (возможно, также ,).Вы можете отсортировать (и uniq -c) их.

sed -n '/dict = {/,/}/ s/:/:/p' inputfiles|tr -d ' \t' | sort

Результат - что-то вроде

'de':'hallo',
'en':'hello',
'en':'hello',
'fa':'سلام
0 голосов
/ 18 мая 2018

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

  • убрать начальные и конечные пробелы из всех строк
  • отсортировать строки
  • сравнить файлыиспользуя comm для получения общих строк между файлами

Итак, вы должны сделать:

sed 's/^\s*//;s/\s*$//' first_file.py | sort > sorted_first_file.py
sed 's/^\s*//;s/\s*$//' second_file.py | sort > sorted_second_file.py
comm -12 sorted_first_file.py sorted_second_file.py

Теперь, чтобы сравнить каждую пару файлов в вашем дереве исходных текстов, вы можете:

  • сначала запустите указанную выше команду sed + sort и создайте sorted_ версии этих файлов, чтобы сократить время
  • , затем выполните команду find, которая для каждогоfilename, запускает команду find и сравнивает этот файл со всеми остальными файлами.

Что-то вроде:

# remove all leading/trailing spaces
find . -name '*.py' -exec sed -i.no_spaces 's/^\s*//;s/\s*$//' {} \;

# on my machine, for some reason, only when using -i the above sed command
# does not work and I have to split it in two.
#find . -name '*.py' -exec sed -i.no_spaces 's/^\s*//' {} \;
#find . -name '*.py.no_spaces' -exec sed -i 's/\s*$//' {} \;

# sort all files
find . -name '*.py.no_spaces' -exec sort {} -o {}.sorted \;

И затем последний шаг - "двойнойfind ":

for filename in $(find . -name '*.py.no_spaces.sorted');
do
    find . -name '*.py.no_spaces.sorted' -not -path "*$filename*" -exec comm -12 "$filename" {} \;
done

Это должно вывести общие строки между всеми файлами.

Примечание: вы, вероятно, тоже хотите удалить пустые строки.Вы можете сделать это с помощью grep перед этим последним шагом.


ПРИМЕЧАНИЕ: если у вас есть относительно большое количество файлов, это займет целую вечность, чтобы закончить.Поскольку алгоритм равен O (n ^ 2), поэтому, если у вас есть 1000 файлов, он делает 1000000 вызовов comm -12.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...