Skip to content

Instantly share code, notes, and snippets.

@gameshler
Last active February 20, 2026 20:58
Show Gist options
  • Select an option

  • Save gameshler/02baf4689dd9bafb824a53c931b75c4a to your computer and use it in GitHub Desktop.

Select an option

Save gameshler/02baf4689dd9bafb824a53c931b75c4a to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
INPUT_FILE="${1:-bookmarks.html}"
PERSONAL_FILE="personal.txt"
WORK_FILE="work.txt"
if [[ ! -f "$INPUT_FILE" ]]; then
echo "Error: $INPUT_FILE not found"
exit 1
fi
CLEAN_FILE="/tmp/bookmarks_clean.html"
PARSED_FILE="/tmp/bookmarks_parsed.txt"
tr -d '\r' < "$INPUT_FILE" > "$CLEAN_FILE"
awk '
BEGIN { depth = 0 }
tolower($0) ~ /<h3/ {
line = $0
sub(/.*<H3[^>]*>/, "", line)
sub(/<\/H3>.*/, "", line)
low = tolower(line)
# Hide root names (no prefix like "Bookmarks toolbar /")
if (low == "bookmarks bar" || low == "other bookmarks" || low == "bookmarks toolbar")
folder[depth] = ""
else
folder[depth] = line
depth++
next
}
tolower($0) ~ /<\/dl>/ {
if (depth > 0) {
depth--
delete folder[depth]
}
next
}
tolower($0) ~ /<a href=/ {
line = $0
url = line
sub(/.*HREF="/, "", url)
sub(/".*/, "", url)
name = line
sub(/.*<A[^>]*>/, "", name)
sub(/<\/A>.*/, "", name)
path = ""
for (i = 0; i < depth; i++) {
if (folder[i] != "")
path = path folder[i] " / "
}
if (path != "")
printf("[%s] %s :: %s\n", substr(path,1,length(path)-3), name, url)
else
printf("%s :: %s\n", name, url)
next
}
' "$CLEAN_FILE" > "$PARSED_FILE"
if command -v fzf >/dev/null 2>&1; then
echo "Select PERSONAL bookmarks (tab to mark, enter to accept)..."
# One interactive selection: what you pick goes to personal.txt
fzf --multi < "$PARSED_FILE" > "$PERSONAL_FILE"
# Everything not selected automatically goes to work.txt
grep -F -x -v -f "$PERSONAL_FILE" "$PARSED_FILE" > "$WORK_FILE"
else
# Fallback without fzf: everything -> personal, work empty
cp "$PARSED_FILE" "$PERSONAL_FILE"
: > "$WORK_FILE"
fi
echo "Saved personal bookmarks to $PERSONAL_FILE"
echo "Saved work bookmarks to $WORK_FILE"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment