diff --git a/inc/lektor/macro.h b/inc/lektor/macro.h
index 712ae9f9a6799646dd2bace4b3d459746631f940..f5a3209085b35d737e6533afefe815e883b2b4bd 100644
--- a/inc/lektor/macro.h
+++ b/inc/lektor/macro.h
@@ -55,6 +55,20 @@
         fprintf(stderr, " ! %s: %s\n", __func__, msg);                  \
         return ret;                                                     \
     }
+#define GOTO_IF(cond, msg, label)                                       \
+    if (cond) {                                                         \
+        fprintf(stderr, " ! %s: %s\n", __func__, msg);                  \
+        goto label;                                                     \
+    }
 
+#define GOTO_UNLESS(cond, msg, label)   GOTO_IF(!(cond), msg, ret)
 #define RETURN_UNLESS(cond, msg, ret)   RETURN_IF(!(cond), msg, ret)
 #define NOTHING                         /* Usefull to return nothing. */
+
+#define STRTOL(ret, str, endptr, err_flag)                              \
+{                                                                       \
+    err_flag = 0;                                                       \
+    errno    = 0;                                                       \
+    ret      = str == NULL ? 0 : strtol(str, &(endptr), 0);             \
+    err_flag = errno != 0 || endptr == str;                             \
+}
diff --git a/meson.build b/meson.build
index 6efa4f3825ea75c16910c5109784d5c2e33f67ef..1184051085b5884573f28add51451d9bcd561f50 100644
--- a/meson.build
+++ b/meson.build
@@ -53,7 +53,6 @@ includes = include_directories('inc')
 
 # Server
 core_deps = [ dependency('sqlite3', version : '>= 3.31.0')
-            , dependency('libpcre')
             , dependency('libcurl')
             , dependency('json-c')
             , dependency('threads', required : true)
diff --git a/src/main/lktadm.c b/src/main/lktadm.c
index cb4a68bd24f944484547066f4a6957547ff0f40f..f43d40c28a220f563898e39caa91ef846e29a500 100644
--- a/src/main/lktadm.c
+++ b/src/main/lktadm.c
@@ -66,16 +66,23 @@ open_db(void)
 noreturn void
 help(void)
 {
-    printf("Usage for lktadm:\n\n"
-           "  --init:    init metadata for all the database according to the root of\n"
-           "             the root of the base\n\n"
-           "  --file <file.mkv, ...>:         set automatically metadata for the file file.mkv\n\n"
-           "  --prompt-file <file.mkv, ...>:  prompt metadata to put for the file file.mkv\n\n"
-           "  --populate-all:                 populate the database with whate is found in the fs\n\n"
-           "  --cat <file.mkv, ...>:          print the metadata of files\n\n"
-           "  --get-id <id>:                  print metadata from kurisu with an id\n\n"
-           "  --down-id <id> <path>:          download a kara from kurisu to a path\n\n"
-           "  --default-conf:                 output to stdout the default configuration file\n\n");
+    static const char *help__ =
+        "USAGE lktadm <COMMAND> [ARGS [...]]:\n"
+        "\n"
+        "COMMANDS:\n"
+        "    init                   the init sub command\n"
+        "    get <id>               get the metadata of a kara from kurisu\n"
+        "    download <id> <path>   download\n"
+        "    cat <path>             display the metadata of a mkv file\n"
+        "    conf                   prints the default config file to stdout\n"
+        "\n"
+        "INIT COMMANDS:\n"
+        "    database               write the default empty database\n"
+        "    popualte               populate the database from the filesystem\n"
+        "    metadata               write metadata to mkv files on the disk using theirs path\n"
+        "    file <path>            init the metadata for a single file by its path\n"
+        "\n";
+    write(1, help__, strlen(help__));
     exit(EXIT_SUCCESS);
 }
 
@@ -131,6 +138,7 @@ init_populate__(struct lkt_cmd_args *args)
 noreturn void
 init_file__(struct lkt_cmd_args *args)
 {
+    open_db();
     int i;
     for (i = 0; i < args->argc; ++i)
         metadata_set_file((char *) args->argv[i], mkvpropedit);
@@ -272,6 +280,7 @@ static struct lkt_cmd_opt options_init[] = {
     { .name = "database",   .call = init_database__ },
     { .name = "populate",   .call = init_populate__ },
     { .name = "metadata",   .call = init_metadata__ },
+    { .name = "file",       .call = init_file__     },
     LKT_OPT_NULL,
 };
 
@@ -293,5 +302,5 @@ static struct lkt_cmd_opt options[] = {
 int
 main(int argc, const char **argv)
 {
-    lkt_cmd_parse(options, argc, argv, help);
+    lkt_cmd_parse(options, argc - 1, argv + 1, help);
 }
diff --git a/src/mkv/write.c b/src/mkv/write.c
index c29dd79ff08ee87b66cad1430dd10b167aaad400..4ebd6b9cc5f84903e83db2c6acb2fab6c366a534 100644
--- a/src/mkv/write.c
+++ b/src/mkv/write.c
@@ -1,8 +1,9 @@
 #define _POSIX_C_SOURCE 200809L
 #define _DEFAULT_SOURCE
 
+#include <lektor/macro.h>
+#include <lektor/defines.h>
 #include <lektor/mkv.h>
-#include <pcre.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <unistd.h>
@@ -14,6 +15,8 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 #include <sys/wait.h>
+#include <sys/types.h>
+#include <regex.h>
 
 static const char *METADATA_TEMPLATE =
     "   <?xml version=\"1.0\" encoding=\"UTF-8\"?>  "
@@ -138,88 +141,51 @@ error:
 static bool
 metadata_from_path(char *const mkvfile, struct kara_metadata *meta)
 {
-    pcre *regex = NULL;
-    pcre_extra *pcre_extra = NULL;
-    bool sta = false;
-    const int sub_str_vec_len = 30;
-    int pcre_error_offset, pcre_exec_ret, sub_str_vec[sub_str_vec_len], i, num;
-    char num_str[LEKTOR_TAG_MAX];
-    const char *substr;
-    char *copy_to;
+    static regex_t regex;
+    static int regex_init = 0;
+    const size_t nmatch = 10;
+    regmatch_t pmatch[nmatch];
+    int reti, sta = false;
+    char msgbuf[LEKTOR_TAG_MAX];
+    char *endptr;
 
     static const char *rgx =
-        "^\\/(?:.+)\\/(vo|va|amv|cdg|autres|vocaloid)\\/"
-        "(jp|fr|en|ru|sp|it|ch|latin|multi|undefined)\\/(.+)\\/"
-        "(.+) - (OP|ED|IS|AMV|VOCA|PV|MV|LIVE)(\\d*) - (.+)\\.mkv$";
-    const char *pcre_error_str = NULL;
-
-    if ((regex = pcre_compile(rgx, 0, &pcre_error_str, &pcre_error_offset, NULL)) == NULL) {
-        fprintf(stderr, " ! metadata_from_path: failed to compile regex\n");
-        return false;
-    }
+        "^/(.+)/(vo|va|amv|cdg|autres|vocaloid)/"
+        "(jp|fr|en|ru|sp|it|ch|latin|multi|undefined)/(.+)/"
+        "(.+) - (OP|ED|IS|AMV|VOCA|PV|MV|LIVE)([[:digit:]]*) - (.+)\\.mkv$";
 
-    pcre_extra = pcre_study(regex, 0, &pcre_error_str);
-
-    if (pcre_error_str != NULL) {
-        fprintf(stderr, " ! metadata_from_path: failed to study regex: %s\n", pcre_error_str);
-        goto error;
-    }
+    if (!regex_init)
+        GOTO_IF(regcomp(&regex, rgx, REG_EXTENDED), "Failed to compile regex", error);
 
     memset(meta, 0, sizeof(struct kara_metadata));
-    memset(num_str, 0, LEKTOR_TAG_MAX * sizeof(char));
-    pcre_exec_ret = pcre_exec(regex, pcre_extra, mkvfile, strlen(mkvfile), 0, 0,
-                              sub_str_vec, sub_str_vec_len);
-
-    if (pcre_exec_ret < 0) {
-        fprintf(stderr, " ! metadata_from_path: PCRE error\n");
+    memset(msgbuf, 0, LEKTOR_TAG_MAX * sizeof(char));
+
+    reti = regexec(&regex, mkvfile, nmatch, pmatch, 0);
+    if (!reti) {
+        /* Match */
+        memcpy(meta->category, mkvfile + pmatch[2].rm_so, pmatch[2].rm_eo - pmatch[2].rm_so);
+        memcpy(meta->language, mkvfile + pmatch[3].rm_so, pmatch[3].rm_eo - pmatch[3].rm_so);
+        memcpy(meta->author_name, mkvfile + pmatch[4].rm_so, pmatch[4].rm_eo - pmatch[4].rm_so);
+        memcpy(meta->source_name, mkvfile + pmatch[5].rm_so, pmatch[5].rm_eo - pmatch[5].rm_so);
+        memcpy(meta->song_type, mkvfile + pmatch[6].rm_so, pmatch[6].rm_eo - pmatch[6].rm_so);
+        memcpy(msgbuf, mkvfile + pmatch[7].rm_so, pmatch[7].rm_eo - pmatch[7].rm_so);
+        memcpy(meta->song_name, mkvfile + pmatch[8].rm_so, pmatch[8].rm_eo - pmatch[8].rm_so);
+    } else if (REG_NOMATCH == reti) {
+        fprintf(stderr, "No match for: %s\n", mkvfile);
         goto error;
-    }
-
-    if (pcre_exec_ret == 0) {
-        // To much -> error in our case //
-        fprintf(stderr, " ! metadata_from_path: To much matches found for file: %s\n", mkvfile);
+    } else {
+        regerror(reti, &regex, msgbuf, sizeof(msgbuf));
+        fprintf(stderr, "Failed to execute regex: %s\n", msgbuf);
         goto error;
     }
 
-    for (i = 1; i < pcre_exec_ret; ++i) {
-        pcre_get_substring(mkvfile, sub_str_vec, pcre_exec_ret, i, &substr);
-
-        if (i == 1)
-            copy_to = meta->song_type;
-        else if (i == 2)
-            copy_to = meta->language;
-        else if (i == 3)
-            copy_to = meta->author_name;
-        else if (i == 4)
-            copy_to = meta->source_name;
-        else if (i == 5)
-            copy_to = meta->category;
-        else if (i == 6)
-            copy_to = num_str;
-        else if (i == 7)
-            copy_to = meta->song_name;
-        else {
-            pcre_free_substring(substr);
-            goto error;
-        }
+    STRTOL(meta->song_number, msgbuf, endptr, reti);
+    if (reti || meta->song_number <= 0)
+        meta->song_number = 1;
 
-        snprintf(copy_to, LEKTOR_TAG_MAX, "%s", substr);
-        pcre_free_substring(substr);
-    }
-
-    meta->song_number = ((num = atoi(num_str)) <= 0) ? 1 : num;
     sta = true;
 error:
-    pcre_free(regex);
-
-    if (pcre_extra != NULL) {
-#ifdef PCRE_CONFIG_JIT
-        pcre_free_study(pcre_extra);
-#else
-        pcre_free(pcre_extra);
-#endif
-    }
-
+    regfree(&regex);
     return sta;
 }