怎样快速找到 elpa 目录下那些重复的包

因为国内网络的原因,有时升级包的时候会中断,这样会造成旧包没有被删除,新包旧包同时存在。有没有什么办法快速找到那些重复的包呢?新包和旧包同名,只是后缀时间戳不一样。但是有时候并不知道包名,这时应该怎么办呢?

列出文件夹再排序就出来了吧。

大概是这几个命令: ls sort uniq -d

对了,ls 后用正则把包名后缀时间戳替换掉。

1 个赞

能不能给一个完整的 :yum:

我比较懒

这一两行命令解决不了吧,要用到循环、变量啥的。懒就放着呗,硬盘又不值钱,.el又小。

就是想看看哪位大神能给个 one-liner,学习一下。

感觉 elpa 目录不干净总是有隐患,我之前碰到过的灵异事件大部分都和包的加载有关

⋊> echo "1
    2
    3
    4
    3
    2
    0" | sort | uniq -d
2
3
1 个赞

@ashfinal 给出的答案一样,但是没有处理包名时间后缀 :thinking:

多谢各位的帮助,可能再加上 sed 就够了

sed 如果只是剔除,那最后得出来的也只是包名,不包括时间戳,如果想要输出带时间戳的结果,必需在比较的过程中对文本顺序做些调整,最后输出的时候还原:

⋊> ls ~/.emacs.d/elpa-26.0.50/ | grep s-20171102.22
# =>
# s-20171102.226
# s-20171102.227

⋊> ls ~/.emacs.d/elpa-26.0.50 | \
    sort | \
    sed 's/^\(.*\)\(-20[0-9]*\.[0-9]*\)$/\2,\1/' | \
    column -t -s ',' | \
    uniq -d -f 1 | \
    awk '{print $2$1}'
# => s-20171102.226
3 个赞
#!/usr/bin/env newlisp
(set 'lst (replace nil (map (lambda (str)
                              (when (set 'tmp (regex "-\\d+.\\d+" str))
                                (replace (first tmp) str "")))
                            (replace "." (replace ".." (directory))))))

(while lst
  (println (pop lst)))

(exit)

Output

>> 0:~/.e/elpa $ ~/sort.lsp                                                                                                                     << 19:18 <]
helm-descbinds
evil-unimpairedpre0.20171005.213835#这个是命名不规范的个例
mwim
evil
iedit
helm-projectile
undo-tree
parinfer
org-plus-contrib
rainbow-delimiters
helm-ag
parent-mode
hydra
evil-mc
epl
google-translate
yasnippet
pcre2el
fuzzy
eyebrowse
...
...

输出结果给 uniq,然后输出给下面的脚本(喂):

#!/usr/bin/env newlisp
(while (read-line) (push (current-line) name))

(dolist (file name)
  (println (append name
                   (1 (sort (map (lambda (f) (replace (append file "-")))
                                 (exec (append "ls" file "*"))))))))

然后传给 rm -rf

1 个赞

赞,但是有一点疑问,我这样在 sed 中使用 regexp 的时候都不工作,还得加上 -E 参数?

噢,系统差异,macOS 下是 BSD Sed,在 Linux 下是 GNU Sed。

1 个赞

要是 ls 的输出能够只包括目录名就完美了,因为 elpa 目录下有时候还会包含与包名类似的单个文件

我这个脚本能过滤文件。。不过估计只能供你参考,因为你不用 newlisp。

原来是 newlisp,厉害了

还有一点差异是我这里sed中正则的组必须用 () 而不是 \(\)

NewLisp 能直接调用 Shell 命令的结果,还内置很方便的 PCRE 正则和可以直接操作字符串的 append pop sort 等函数。作为脚本语言还是很不错的。

Emacs Lisp 不靠第三方库作为脚本不太够用。Common Lisp 和 Scheme 只有外部的正则库。

1 个赞

等有时间了研究研究,多谢推荐!

@twlz0ne 命令行用的很溜哇 :+1:

我还没有细看,大概思路就是这个样子。


补充一下:我觉得重复的包这个问题本来可以避免。不过现在我 emacs 还是裸状态,不能验证一些想法。

包管理器下载的是 zip 包吧,下载完毕应该检验一下是不是完整。不完整就不要解压,或者像 brew 那样添加个 .imcompleted 后缀。现在新包/破损包和能用的包完全没有区分,真是让人蛋疼。

刚到 elpa 看了下是 tar 包,而且有签名验证。那估计是一些包顺利解压,但是安装/加载时 elip 出错,然后老包没有删除。

list-packages 里面不就能直接看见吗?直接在那边删除就行吧。

那可要一个个手动看过去