Skip to content

Instantly share code, notes, and snippets.

@bradystroud
Created July 30, 2025 06:42
Show Gist options
  • Select an option

  • Save bradystroud/24af8d6fa48c37987a487b454449225b to your computer and use it in GitHub Desktop.

Select an option

Save bradystroud/24af8d6fa48c37987a487b454449225b to your computer and use it in GitHub Desktop.
Safari history export
#!/bin/bash
OUTPUT="safari_history.md"
echo "# Safari Browsing History" > "$OUTPUT"
echo "" >> "$OUTPUT"
PROFILE_DIR="$HOME/Library/Containers/com.apple.Safari/Data/Library/Safari/Profiles"
TMPFILE=$(mktemp)
QUERY="SELECT datetime(history_visits.visit_time + 978307200, 'unixepoch', 'localtime') AS visit_date, history_items.url, history_items.visit_count FROM history_visits JOIN history_items ON history_items.id = history_visits.history_item ORDER BY visit_date DESC;"
# Export from profiles
for dir in "$PROFILE_DIR"/*; do
DB="$dir/History.db"
if [ -f "$DB" ]; then
echo "Exporting from $DB..."
sqlite3 "$DB" "$QUERY" >> "$TMPFILE"
fi
done
# Export from main profile
MAIN_DB="$HOME/Library/Safari/History.db"
if [ -f "$MAIN_DB" ]; then
echo "Exporting from main Safari history..."
sqlite3 "$MAIN_DB" "$QUERY" >> "$TMPFILE"
fi
# Process and group by date
echo "Processing results..."
awk -F'|' '
{
split($1, datetime, " ");
date = datetime[1];
url = $2;
key = date "|" url;
if (!seen[key]++) {
entries[date] = entries[date] "- " url "\n";
dates[date] = 1;
}
}
END {
for (date in dates) print date > "/tmp/dates_unsorted.txt";
"sort /tmp/dates_unsorted.txt" | getline n;
while ((getline date < "/tmp/dates_unsorted.txt") > 0) {
print "### " date;
printf "%s", entries[date];
print "";
}
}
' "$TMPFILE" >> "$OUTPUT"
rm "$TMPFILE"
echo "✅ Done! Output saved to $OUTPUT"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment