Skip to content

Instantly share code, notes, and snippets.

@goyalankit
Last active October 28, 2023 05:07
Show Gist options
  • Save goyalankit/a1c88bfc69107f93cda1 to your computer and use it in GitHub Desktop.
Save goyalankit/a1c88bfc69107f93cda1 to your computer and use it in GitHub Desktop.
Import bash history to zsh history.
#################################################################
# = This script transfers bash history to zsh history
# = Change bash and zsh history files, if you don't use defaults
#
# = Usage: ruby bash_to_zsh_history.rb
#
# = Author: Ankit Goyal
#################################################################
# change if you don't use default values
BASH_HISTORY_FILE_PATH="#{ENV['HOME']}/.bash_history"
ZSH_HISTORY_FILE_PATH="#{ENV['HOME']}/.zsh_history"
# Read the bash history file
bash_hist_file = File.read(BASH_HISTORY_FILE_PATH)
# Get the list of commands from bash history hile
command_list = bash_hist_file.split("\n")
# Open the zsh history file
zsh_hist_file = File.open(ZSH_HISTORY_FILE_PATH, "a")
# Get timestamp required for zsh history file format and update the history file
time = Time.now.to_i
command_list.each do |command|
time += 1
zsh_hist_file.write(": #{time}:0;#{command}\n")
end
# Close the file
zsh_hist_file.close
@alejoberman
Copy link

Works fine and fast! Thank you!

@leggiero
Copy link

leggiero commented Aug 9, 2017

Awesome script! Worked like a charm. Thank you for sharing!

@objectuser
Copy link

Thanks! 🥇

@tonyslowdown
Copy link

Thank you! For anyone else who uses this, if you get utf-8 errors, try upgrading ruby

@kietoparao
Copy link

kietoparao commented Apr 8, 2018

Thank you for the script, it worked!

Only thing I had to modify is the time = Time.now.to_i line of your script, because it was giving me future times for the commands transfered from the old ~/.bash_history:

19070* 2018-04-08 15:45  git pull
19071* 2018-04-08 15:45  makepkg -sci    # <--- old .bash_history
19072* 2018-04-08 12:55  bash            # <--- new .zsh_history
19073* 2018-04-08 12:52  echo $SHELL

Just changing it to time = Time.now.to_i - (nr. of lines in old .bash_history) (e.g.: time = Time.now.to_i - 11469) fixed this and now I get the following view with history from zsh:

10534  2018-04-08 12:58  git pull
10535  2018-04-08 12:58  makepkg -sci    # <--- old .bash_history
10536  2018-04-08 13:14  bash            # <--- new .zsh_history
10537  2018-04-08 13:14  echo $SHELL

@szotsaki
Copy link

If you have invalid UTF-8 sequences in your .bash_history, just remove those characters with iconv like

iconv -f UTF-8 -t UTF-8//IGNORE .bash_history > .bash_history-utf8

@tkrshn
Copy link

tkrshn commented Aug 14, 2018

Thank you.

@bigplum
Copy link

bigplum commented Oct 11, 2018

one line command: awk '{print " :0:;"$1}' .bash_history > .zsh_history

@gimpf
Copy link

gimpf commented Dec 2, 2018

one line command: awk '{print " :0:;"$1}' .bash_history > .zsh_history

Almost... $1 needs to be $0, or there won't be any args, and > should be >>, to append instead of replace. Also, at least for my history config, there's a : missing at the beginning. Finally, I'd not import duplicates, ergo sort ~/.bash_history | uniq | awk '{print ": :0:;"$0}' >> ~/.zsh_history.

@ldakhoa
Copy link

ldakhoa commented Mar 2, 2019

Thanks, it's work

@CNG
Copy link

CNG commented Mar 5, 2019

I was surprised to see the top Google results for this are Ruby and Python scripts, huh! Then I missed the awk command at the bottom here and did it with Perl. First I checked the format of both my histories:

$ head -n1 ~/.zsh_history
: 1551826967:0;ls -al ~
$ head -n2 ~/.bash_history
#1532234168
exit

Then wrote a Perl command that I ran under Bash so Zsh would not be running and conflict (from Zsh, I ran exec bash and confirmed Zsh was not running with pgrep zsh):

perl -0777 -pe 's/^#(\d+)\n(.*?)$/: \1:0;\2/gm' ~/.bash_history >> ~/.zsh_history

@panelladavide
Copy link

Thanks, it's work fine!

@theposey
Copy link

theposey commented May 7, 2019

awesome dude

@tkainrad
Copy link

Thanks, works perfectly.

@davgilso
Copy link

Worked perfectly.

Worth noting that you should remember to increase your SAVEHIST value first.

@marchrius
Copy link

@robertstrom
Copy link

getting this error message - anyone have a solution?

./bash_to_zsh_history.rb: line 15: syntax error near unexpected token (' ./bash_to_zsh_history.rb: line 15: bash_hist_file = File.read(BASH_HISTORY_FILE_PATH)'

Ruby version is ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]

@goyalankit
Copy link
Author

goyalankit commented Nov 11, 2019

getting this error message - anyone have a solution?

./bash_to_zsh_history.rb: line 15: syntax error near unexpected token (' ./bash_to_zsh_history.rb: line 15: bash_hist_file = > File.read(BASH_HISTORY_FILE_PATH)'

Ruby version is ruby 2.6.3p62 (2019-04-16 revision 67580) [universal.x86_64-darwin19]

@robertstrom You probably copy-pasted the script wrong. There's an extra ' at the end of line 15.

@danielcomas25
Copy link

Worked perfectly! Thanks!

@mscalora
Copy link

mscalora commented Nov 23, 2019

Thanks bigplum & gimpf,

sort ~/.bash_history | uniq | awk '{print ": :0:;"$0}' >> ~/.zsh_history

just what I needed on a VM without ruby installed

@fharper
Copy link

fharper commented Dec 2, 2019

Thanks for the script

@Crow-head
Copy link

Awesome work! Thank you!

@cellcoresystems
Copy link

clean, simple and fast - thx

@cad-asura
Copy link

Personally I found awk and PERL to be to heavy weight :) So I went for

cat ~/.bash_history | cut -d' ' -f1- | sort | uniq | xargs -I % echo ": $(date +%s):0;" % >> ~/.zsh_history

@frostyandy2k
Copy link

Personally I found awk and PERL to be to heavy weight :) So I went for

cat ~/.bash_history | cut -d' ' -f1- | sort | uniq | xargs -I % echo ": $(date +%s):0;" % >> ~/.zsh_history

This worked like a charm on OSX Catalina from bash to zsh.

@bsa7
Copy link

bsa7 commented Aug 6, 2020

Script is working for me. Ubuntu 20.20. History moved. Thank you!

@JuniorJPDJ
Copy link

Guys ;)
cp ~/.bash_history ~/.zsh_history works
Probably zsh wrote some import from just cmdlines in history

@samypr100
Copy link

Since I didn't see trusty old sed, here's one I made with my friend sed

cat ~/.bash_history | uniq | sed "s/^/\: $(date +%s)\:0;/" >> ~/.zsh_history

@brutoid
Copy link

brutoid commented Jun 18, 2022

Since I didn't see trusty old sed, here's one I made with my friend sed

cat ~/.bash_history | uniq | sed "s/^/\: $(date +%s)\:0;/" >> ~/.zsh_history

Works a treat. Cheers.

@remotelyimin
Copy link

Thanks a lot brother.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment