在看到被接受的答案有一个关键错误后,我不得不修复它并在这里发布。
A.B的答案遍历每个
list
文件中的条目,如果该文件中的任何条目在系统上安装的软件包数量为0,无论有多少条目有软件包,都会将整个文件删除。
它还完全忽略了与预定义格式不匹配的任何条目。它不会考虑它们。
此外,脚本只处理匹配的条目。它不会对空文件进行任何操作。
所以我修复了脚本,如下所示:
#!/usr/bin/env bash
for f in /etc/apt/sources.list.d/*.list; do
fileTotal=0
echo "FILENAME: $f"
while read -r ENTRY ; do
echo "ENTRY: $ENTRY"
ENTRY=$(echo "$ENTRY" | sed 's/\[.*\] //')
HOST=$(cut -d/ -f3 <<< "$ENTRY")
if [ "ppa.launchpad.net" = "$HOST" ]; then
USER=$(cut -d/ -f4 <<< "$ENTRY")
PPA=$(cut -d/ -f5 <<< "$ENTRY")
packageCount=$(awk '$1=="Package:" {if (a[$2]++ == 0) {system("dpkg -l "$2)}}' /var/lib/apt/lists/*"$USER"*"$PPA"*Packages 2>/dev/null | awk '/^ii/' | wc -l)
else
USER=$(cut -d/ -f3 <<< "$ENTRY")
PPA=$(cut -d/ -f4 <<< "$ENTRY")
packageCount=$(awk '$1=="Package:" {if (a[$2]++ == 0) {system("dpkg -l "$2)}}' /var/lib/apt/lists/*"$USER"*Packages 2>/dev/null | awk '/^ii/' | wc -l)
fi
((fileTotal+=packageCount))
printf '\t%s\n' "REPOSITORY: $USER/$PPA"
printf '\t%s\n' "$packageCount package(s) installed"
echo
done < <(grep -Po "(?<=^deb\s).*?(?=#|$)" "$f")
unrecognizedCount=0
while read -r ENTRY ; do
((unrecognizedCount++))
printf '\t%s\n' "Unrecognized entry: $ENTRY"
done < <(grep -Pv "(?=^deb\s)|(?=^#).*" "$f" | grep -P "[^\s]")
echo "$fileTotal packages installed"
echo "$unrecognizedCount entries unrecognized"
if [ "$fileTotal" -eq 0 ] && [ "$unrecognizedCount" -eq 0 ]; then
if [ "$1" == "--delete" ]; then
sudo rm "$f"
sudo rm "$f".*
echo "$f deleted"
else
echo "Deletable"
fi
fi
echo "----------------------------"
done
使用方法完全相同,只是
--delete
选项仅在没有任何已安装软件包的条目和无法识别的条目时才删除文件。空白和注释行不计入条目。
即使我已经考虑了所有可能,这仍然是一个未经测试的、需要以sudo
权限运行的脚本,请先备份/etc/apt/sources.list.d
目录中的所有内容。
y-ppa-manager
。 - Byte Commander