Why is my cut command not working ?

OS : RHEL 6.8
Shell : bash

I want to remove all lines like below from the history output as it has password.

$ history | grep sqlplus
  239  sqlplus jn_usr/dxc825#@10.5.12.106/OCSGPD
  256  sqlplus osb_soa/KD1egM09@10.5.12.196/BSOAPRD
  279  sqlplus jn_usr/dxc825#@10.80.16.219/OCSGPD
  402  sqlplus jn_usr/dxc825#@10.80.16.219/MNXSPD
  868  sqlplus jn_usr/dxc825#@10.80.16.219/OCSGPD
  932  sqlplus osb_usr/vsNfCha92@10.5.12.106/OCSGPD
  934  sqlplus osb_usr/vsNfCha92@10.5.12.106/OCSGPD

To remove all the above lines ,I wanted to fetch the first field (239, 256, ....) from the above history command output and then run history -d in loop like below.

# untested
for h in $(history | grep sqlplus | cut -d' ' -f1); do history -d $h; done

But, the cut doesn't work as expected. I tried the following 2 options

The following returns blank
$ history | grep sqlplus | cut -d' ' -f1

The following returns lot of empty lines and few lines at the bottom as shown below

$ history | grep sqlplus | cut -d' ' -f2






1004
1021
1022
1023
1024
1026
1027
1028
1029
1030

cut does not concatenate delimiters but increases the field count for every single one it encounters. Try

history | awk '/sqlplus/ {print $1}'

Be aware that the history offset changes with history lines deleted; you may need to sort them reversely.

1 Like

Thank You Rudic.

One more question.
Any idea how I can get the below for loop to work in bash ?
I want to fetch each value from history | awk '/sqlplus/ {print $1}' command output and then run history -d on each value.
But, it doesn't seem to work well as shown below

$ for h in $(history | awk '/sqlplus/ {print $1}'); do history -d $h; done
-bash: history: 1019: history position out of range
-bash: history: 1031: history position out of range
-bash: history: 1032: history position out of range
-bash: history: 1033: history position out of range
-bash: history: 1034: history position out of range
while [ -n "$(history | awk '/sqlplus/')" ] ; do history -d $(history | awk '/sqlplus/ {print $1; exit}') ; done
1 Like

I'm a bit puzzled. Although I warned that the history offset may change during the operations, the numbers should be "in range".
I don't really like the idea of working on "moving targets". rdrtx1's proposal nails one single history entry at a time, and chances are good this will work. Another untested / unproven option might be to update the history file ( -a option?), dump the entire history to a file, eliminate all sqlplus entries, and write that updated file to the history file.

1 Like

I have been playing around with this and it appears that multi-line commands go into the history as a single command until you log off. As an example if you typed a command like:

while read server ; do
    sqlplus jn_usr/dxc825#@$server/OCSGPD
done < hostlist

history will display:

  506  while read server ; do
    sqlplus jn_usr/dxc825#@$server/OCSGPD
done < hostlist
  507  cd ..

You might need some magic to identify and delete these history lines, or ensure you log back in before trying the delete.

1 Like