检查多个文件中是不是存在多个字符串

Posted

技术标签:

【中文标题】检查多个文件中是不是存在多个字符串【英文标题】:Checking if multiple strings exist in multiple files检查多个文件中是否存在多个字符串 【发布时间】:2022-01-08 18:35:10 【问题描述】:

我有一个 JSON 对象的翻译文件,它可能包含更多 JSON 对象,我需要找到丢失的翻译。 JSON 文件前:

export const locale = 
    lang: 'en',
    data: 
        'NAV': 
            'APPLICATIONS': 'Applications',
            'DASHBOARDS'  : 'Dashboards',
            'CALENDAR'    : 'Calendar',
            'ECOMMERCE'   : 'E-Commerce',
            'ACADEMY'     : 'Academy',
            'MAIL'        : 
                'TITLE': 'Mail',
                'BADGE': '25'
            ,
            'MAIL_NGRX'        : 
                'TITLE': 'Mail Ngrx',
                'BADGE': '13'
            ,
            'CHAT'        : 'Chat',
            'FILE_MANAGER': 'File Manager',
            'CONTACTS'    : 'Contacts',
            'TODO'        : 'To-Do',
            'SCRUMBOARD'  : 'Scrumboard'
        
    
;

我需要获取每个翻译,这是最低级别的项目(例如 data.NAV.MAIL.BADGE 或 data.NAV.APPLICATIONS),并查看它是否存在于我的项目的文件目录中。

打开大量文件是否效率低下,或者与通过翻译和打开每个文件(可能有数千个文件)进行翻译相比,这种差异可以忽略不计?

我正在考虑递归地展平对象,所以我得到一个包含所有键的平面对象,获取每个文件,并检查每个字符串是否存在。如果是这样,我将它移动到找到字符串的不同对象,因此不会再次检查它。不使用原始对象中剩余的任何内容。我还将添加 git ignore 中的任何内容以在此处忽略,因为它不相关。

我认为递归地进入目录中未被忽略的每个文件,然后递归地检查密钥是否在文件中,然后进入下一个密钥(如果存在)并检查可能会更好?

有什么我可能会遗漏的东西可以提高效率吗?

【问题讨论】:

【参考方案1】:

除非您有太多数据无法放入内存(我真的怀疑翻译文件,但谁知道呢?),那么我认为您最好将所有文件中的数据收集到一个数组中并在它们全部加载后处理该数组。

处理它可以相当容易。这是一个实现:

const uniq = (xs) => [... new Set (xs)]

const getLeafPaths = (obj) =>
  Object (obj) === obj
    ? Object .entries (obj) .flatMap (
        ([k, v]) => getLeafPaths (v) .map (p => k + (p.length ? '.' + p : ''))
      )
    : ['']

const missing = (
  locales,
  localeKeys = locales .map (locale => [locale .lang, getLeafPaths (locale .data)]),
  allKeys = uniq (localeKeys .flatMap (([, keys]) => keys)) .sort()
) => (
  allKeys,
  missing: Object .fromEntries (
    localeKeys .map (([lang, keys]) => [lang, allKeys .filter (k => ! keys .includes (k))])
  )
)

const locales = [lang: "en", data: NAV: APPLICATIONS: "Applications", DASHBOARDS: "Dashboards", ECOMMERCE: "E-Commerce", ACADEMY: "Academy", MAIL: BADGE: "25", MAIL_NGRX: TITLE: "Mail Ngrx", CHAT: "Chat", FILE_MANAGER: "File Manager", TODO: "To-Do", SCRUMBOARD: "Scrumboard", lang: "es", data: NAV: APPLICATIONS: "Aplicaciones", CALENDAR: "Calendario", ECOMMERCE: "Comercio electrónico", MAIL: TITLE: "Mail", BADGE: "26", MAIL_NGRX: BADGE: "14", CHAT: "Chat", FILE_MANAGER: "Administradora de archivos", TODO: "Hacer", SCRUMBOARD: "Tablero de melé", lang: "ru", data: NAV: DASHBOARDS: "Дашборды", CALENDAR: "Календарь", ACADEMY: "Академия", MAIL: TITLE: "Почта", MAIL_NGRX: TITLE: "Почта Ngrx", BADGE: "15", FILE_MANAGER: "Файловый менеджер", CONTACTS: "Контакты", TODO: "Делать"]

console .log (missing (locales))
.as-console-wrapper max-height: 100% !important; top: 0

辅助函数uniq 只是查找数组中唯一元素的集合。

getLeafPaths 更有趣。它找到路径,作为对象中所有叶节点的'.'-分隔的属性名称。对于示例对象的 data 属性,它返回

[
  "NAV.APPLICATIONS", "NAV.DASHBOARDS", "NAV.ECOMMERCE", "NAV.ACADEMY", 
  "NAV.MAIL.BADGE", "NAV.MAIL_NGRX.TITLE", "NAV.CHAT", "NAV.FILE_MANAGER", 
  "NAV.TODO", "NAV.SCRUMBOARD"
]

主函数missing 获取列表中每个语言环境对象的路径,将键组合成一个主列表,然后返回一个带有主列表的对象以及每个语言的列表,来自主列表未找到每种语言的列表。输出如下所示:


  allKeys: [
    "NAV.ACADEMY", "NAV.APPLICATIONS", "NAV.CALENDAR", "NAV.CHAT",
    "NAV.CONTACTS", "NAV.DASHBOARDS", "NAV.ECOMMERCE", "NAV.FILE_MANAGER",
    "NAV.MAIL.BADGE", "NAV.MAIL.TITLE", "NAV.MAIL_NGRX.BADGE",
    "NAV.MAIL_NGRX.TITLE", "NAV.SCRUMBOARD","NAV.TODO"
  ],
  missing: 
    en: ["NAV.CALENDAR", "NAV.CONTACTS", "NAV.MAIL.TITLE", "NAV.MAIL_NGRX.BADGE"],
    es: ["NAV.ACADEMY", "NAV.CONTACTS", "NAV.DASHBOARDS", "NAV.MAIL_NGRX.TITLE"],
    ru: ["NAV.APPLICATIONS", "NAV.CHAT", "NAV.ECOMMERCE", "NAV.MAIL.BADGE", "NAV.SCRUMBOARD"]
  

如果您已经有了主列表,这可以简化为简单地将其传递给 missing 而不是生成它。

【讨论】:

以上是关于检查多个文件中是不是存在多个字符串的主要内容,如果未能解决你的问题,请参考以下文章

如何使用BufferedReader检查csv中是不是存在多个条件字符串?

Shell如何检查文件中的一行中是不是存在模式

多个文件存在检查?更好的方法?

检查Java中是不是存在多个文件

VB检查多个文件是不是存在

检查字符串是不是包含Python中数组中的多个元素