vi on multiple files

— 2019 xp: I find it useful to quickly exit vi, examine another file, then use bash to recycle previous (long) vi-launch command.

I rely heavily on the fact that vi remembers the last cursor (and search pattern) per file.

Whenever I run a vi-launch command, I quickly decide on file1 file2 file3 names, picking and shuffling among the hottest files.


[3/4] means vi receives 3 keystrokes; we hit 4 keys including shift or ctrl …

–“split” solution by Deepak M

vi file1 # load 1st file

  • :sp file2 # to show 2nd file upstairs
  • :vsp file3 # to show 2nd file side by side
  • You end up with  — file2 and file3 side by side upstairs, and file1 downstairs!
  • [2/3] ctrl-ww # To move cursor to the “next” file, until it cycles back

–the q( :e ) solution

vi file1 # load 1st file

  • :e file2 # to put 2nd file on foreground
  • [1/3] ctrl-^ — to switch to “the other file”
  • This solution is non-ideal for moving data between files, since you must save active file before switching and you can’t see both files

–editing 3 or more files

  1. vi file1 file2 file3
  2. q(:n) to switch to next, q(:N) for previous…
  3. q(:args) shows all files with current file highlighted
  • –Suppose now you are at file2.
  • q(:e file4) works. q(^) will toggle between file2 and file4
  • However, q(:n :N  :args) only work on the original list, not new files from q(:e)

q(:n :N ^) always shows the current filename in status bar:)

git | diff | make file6 appear before file2

The pain — a big commit touches on too many files, 3 of them major changes, while 5 files have cosmetic changes. In git-diff or git-difftool, I want to focus on the 3 major files.

Some developers would want to split the big commit into a “major” and a “cosmetic” commit, but one of the snapshots would be half-cooked and unusable. In such a case, the commit comment would warn “This commit is part of a bigger change. Please do not build this commit alone”.

As an alternative we can make the 3 major files show up first (or last) in diff. You can put the content below in src/diffOrder.txt and use it as instructed. All unspecified files would show up in natural order.

# git diff -O src/diffOrder.txt
# check EACH line below to ensure unix line ending, even if entire file is unix-style.
# wildcards are needed below.


effectively ignore whitespace change]code review #perl

$ perl -pe ‘s/\s//g’> new
$ git checkout some-commit
$ perl -pe ‘s/\s//g’> old
$ diff old new # should show no discrepancy

This worked for me. Entire file is flattened to a single long string.

IIF the whitespace change is only and always confined with a line i.e. no line splitting/joining , then perl  -l -pe is more useful.


MSOL defer-send rule #3spaces

I have used this type of rules in many companies. My current set-up is —

Apply this rule after I submit a msg marked as Normal importance: defer delivery by 1 minute.

I wish there’s a “importance = A or B” condition.

right_click in mswe

Scenario: If you left-click (even if to the right side) to select file1.txt, then right click, you would get the per-file context menu showing Copy/Cut/Delete etc.

Scenario: If you directly right click in an empty space (even if to the right side of some file1.txt), you get the per-dir context menu.

Q: Why no file selected?  Suppose you do a right-click to the right of file1.txt. Before you release the right button, file1.txt may be highlighted temporarily but not selected. After you release the right button, you will see no file selected and you get the per-dir context menu.

Scenario: What if you have already selected file1.txt and now you want the per-dir context menu? Confusing… Solution — Just right-click in another empty space, perhaps to the right of file2.txt. Again, you will see no file selected.

perl regex top3 tips #modifier /m /s shows

The part of the (haystack) string that actually matched the (needle) pattern is automatically stored in q[  $& ]

Whatever came before the matched section is in $` and whatever was after it is in $'. Another way to say that is that $` holds whatever the regular expression engine had to skip over before it found the match, and $' has the remainder of the string that the pattern never got to. If you glue these three strings together in order, you’ll always get back the original string.

— /m /s clarification:

  1. By default, q($) + q(^) won’t match newline. /m targets q($) and q(^)
  2. By default, the dot q(.) won’t match newline. /s targets the dot.
  3. The /m and /s both help get newlines matched, in different contexts.

Official doc says:

  1. /m  Treat the string being matched against as multiple lines. That is, change "^" and "$" from matching the start of the string’s first line and the end of its last line to matching embedded start and end of each line within the string.
  2. /s  Treat the string as single line. That is, change "." to match any character whatsoever, even a newline, which normally it would not match.
  3. Used together, as /ms, they let the "." match any character whatsoever, while still allowing "^" and "$" to match, respectively, just after and just before newlines within the string.

q[cannot open shared object file]

strace -e trace=open myprogram can be used on a working instance to see where all the SO files are successfully located.

— Aug 2018 case: in QA host, I hit “error while loading shared libraries: … No such file or directory”

I can see this .so file so I used LD_LIBRARY_PATH to resolve it.

Then I get “error while loading shared libraries: … No such file or directory”. I can’t locate this .so, but the same executable is runnable in a separate HostB. (All machines can access the same physical file using the same path.)

I zoomed into the HostB and used “ldd /path/to/executable”. Lo and behold, I can see why HostB is lucky. The .so files are located in places local in HostB … for reasons to be understood.

— May 2018 case:

The wording should be “cannot locate ….”

I fixed this error using $LD_LIBRARY_PATH

The *.so  file is actually specified as a -lthr_gcc34_64 option on the g++ command line, but the file was not found at startup.

I managed to manually locate this file in /a/b/c and added it :


bash: split long command to multiple lines

I managed to split a huge g++ command line  to about 300 lines… much more readable.

The trick:

  • terminate each line with a space, a backslash and … NO trailing space
  • my perl one-liner must user four backslashes to insert that single backslash, then another \n
  • total there are 5 backslashes in a row.

Here’s the command

perl -pe "s/ -/ \\\\\n-/g"

MSOL q[Received]: space-sav`custom format

–based on

IIf(Date()=int([Received]),Format([Received],”hh:mm”),IIf(Date()-[Received]<7,format([Received],”ddd m/d”),format([Received],”d mmm yy”)))

Warning: need to clean up the double-quotes after copy-paste from this blogpost!

I name it “-myDT3” — 3 types of values

Q: can I share this custom column between Inbox/Deleted/Sent?
A: Unsuccessful try in 2010

Problem — unsortable
Solution — add the original Received field, but keep it razor thin

How to edit the formula: FieldChooser -> User-defined (usually empty) -> drag the new field in -> edit -> drag it out

git | diff highlights trailing space

By default there’s a default-enabled highlight (in red) of trailing spaces. I encounter it all the time when running git-diff. Extremely distracting.

$ git config core.whitespace  trailing-space # the dash before “trailing” disables it

Beware: when you copy-paste into a command window, the dash may become something else 😦

If successful, this command adds a line into .git/config like

whitespace = -trailing-space

You can remove this line to restore the “factory default”.

stack 2 windows above/below #win7

based on

Scenario — On my vertical monitor I want two windows A and B stacked; on my other monitor I want one big window; total 3 windows.

Solution —

  • minimize all other windows
  • right click on taskbar -> showWindowsStacked

Note to show windows side by side there are many options like winKey and snap

JDK + eclipse install: %%preference

  • C:/j8 or j801 # I prefer shorter path. I almost never have two versions of java on one machine
    • There’s an embedded ./jre directory for a so-called “private JRE”
  • public JRE is optional and should be installed outside JDK directory, but I have not needed it since I started using java.
  • —-eclipse: I prefer the simple zip file download
  • C:/ide/elcipse #worked OK
  • c++ide? can use c:/ide/eclipseCDT.


symlink/hardlink: Win7 or later is a 2017 article.

The mklink command can create both hard links (known as “hard links” in Windows) and soft links (known as “symbolic links” in Windows).

On Windows XP, I have used “Junction.exe” for years, because mklink is not available.

discover cpu count ] my machine #lscpu

NIC — There’s another blog post

$ lscpu
Architecture: x86_64
CPU op-mode(s): 32-bit, 64-bit
Byte Order: Little Endian
CPU(s): 16
On-line CPU(s) list: 0-15
Thread(s) per core: 1
Core(s) per socket: 8
CPU socket(s): 2
NUMA node(s): 2
L1d cache: 32K
L1i cache: 32K
L2 cache: 256K
L3 cache: 20480K

$ less /proc/cpuinfo|egrep 'core id|processor'  # on the same machine shows

16 “processors”, but #0 and #1 have the same core-id! Total 8 core-id values. I think this is because in each (of two) socket, there are 8 cores with unique core-id values.

dmesg | grep rocessor # doesn’t work any more

dxdiag # windows

dxdiag /t c:\deldel.txt
find “CPU” c:\deldel.txt # copy-paste may not work

python run complex external commands #subprocess

I prefer one single full-feature solution that’s enough for all my needs. The os.system() solution is limited. The subprocess module is clearly superior. One of the simplest features is

>>>[“ls”, “-l”])

If you need redirection and background, then try the single-string version

>>>‘ls /tmp > /tmp/a.log &’, shell=True) # output goes to STDOUT, hard to capture

## vi (+less) cheatsheet

Note q[less] not q[more[ can open *.gz files 🙂 has some tricks including how to make vim remember last edit location, but make sure your ‘vi’ command actually runs viM !

  • ~~~~ command mode #roughly ranked
  • [2/3] :↑ (i.e. up-arrow) — cycle through previous :commands
  • [3] dt — “dta” delete until the next “a”
  • [2]: 6x — delete 6 chars
  • [2] 9s — wipe out 9 characters (including current) and enter insert-mode. Better than R when you know how many chars (9) to change
    • to delete 5 characters … there is NO simpler keystroke sequence
  • R — Overwrite each character one by one until end of line. Useful if the replacement content is similar to original?
  • Ctrl-R to re-do
  • cw — wipe out from cursor to end of word and puts you into insert mode
    • c2w or 2cw
  • :se list (or nolist) to reveal invisible chars
  • C — wipe out from cursor to END of line and puts you into insert-mode
  • capital O — open new line above cursor
  • A — to append at END of current line
  • :sy off  — get rid of color scheme
  • :syntax off # is the long form
  • from inside q(LESS), type a single “v” to launch vi

[3/4] means vi receives 3 keystrokes; we hit 4 keys including shift or ctrl …

–paging commands in vi and less

  • jump to end of file: capital G == in both vi and LESS
  • jump to head of file: 1G == in both vi and LESS
  • page dn: Ctrl-f == in both; LESS also uses space
  • page up: Ctrl-b == in both; LESS also uses b


converting btw epoch, HHMMSS ..

  • Note epoch is second-level, not millisecond level.
  • Note epoch is timezone agnostics. It’s always defined in UTC.
  • Note struct tm is the workhorse. It can break up a time object into the year/weekday/…/second components

—to convert from epoch to HHMMSS:

—to convert current time to int epoch number:

—epoch timestamp is typically in seconds

  • 1513961081 — 10 digits, seconds since Epoch
  • 1511946930032722000 — 19 digits, nanosec since Epoch

split std::string on Custom delimiter #practice every6M

See also post on csv string parse…

For a longer delimiter, you may need string.find() has my own tested solution parsing individual tree node details from a stringstream

ifstream f1(fileName.c_str());
string line;
while(getline(f1, line)){
  for(int i=1; ;++i){
        int pos = line.find_first_of("\t");
        string token = line.substr(0,pos);
        cerr<<i<<" : " <<token<<endl;
        if (line == token) break; //there's no more tab in the line
        line = line.substr(pos + 1);

///// a simpler method:
istringstream lineStream("denmark sweden   india us"); //consecutive spaces are Not treated as one
string outputToken;
int main(){
  while (
    getline(lineStream, outputToken, ' ')) // <-- the only thing to remember
        cout << outputToken << endl;

custom delimiter for cin operator>> #complicated

Tested but is too hard to remember. Better use the getline() trick in

struct comma_is_space : std::ctype<char> { //use comma as delimiter
  comma_is_space() : std::ctype<char>(get_table()) {}
  static mask const* get_table() {
    static mask rc[table_size];
    rc[','] = std::ctype_base::space;
    return &rc[0];

istringstream iss(line);
iss.imbue(locale(cin.getloc(), new comma_is_space));

binary search in sorted vector of Tick pointer

Note the mismatched args to the comparitor functions.

(I was unable to use a functor class.)

std::vector<Tick const*> vec;
int target;
bool mylessFunc(Tick const * tick, unsigned int target) {
     //cout<<tick->ts<<" against "<<target<<endl; 
     return tick-ts < target;
lower_bound(vec.begin(),vec.end(),target, mylessFunc);

bool mygreaterFunc(unsigned int target, Tick const * tick){
     //cout<<a->ts<<" against "<<target<<endl; 
     return tick->ts > target;
upper_bound(vec.begin(),vec.end(),target, mygreaterFunc)

WordPad : rich-text note taker

I found WordPad RTF files a good middle ground between ascii text and MSWord files.

  • 🙂 basic text effects like background+font colors
  • 🙂 footprint is comparable to ascii, much smaller than MSWord files.
    • Q: How about after compression?
  • 🙂 how about copying to Linux? tested

Verdict —

  1. default general-purpose note-taker remains ascii, but
  2. for office work notes with text highlighting, let’s try WordPad more often. But let’s not become dependent. Convert old rtf notes to ascii.


This is related to q[cannot open shared object file]

See for the RUNPATH

q(objdump) can inspect the binary file better than q(ldd) does.

q(ldd) shows the final, resolved path of each .so file, but (AFAIK) doesn’t show how it’s resolved. The full steps of resolution is described in

q(objdump) can shed some light … in terms of DT_RUNPATH section of the binary file.

SIMPLEST if-true/if-false ] bash

I often need a manual switch in source code. I can make a one-char change to turn on/off a block.

if (0) and if (1) is good enough in c/python. Java must use if(true)

In bash, I now use

  • if [ -e / ] # unconditionally true
  • if [ -d / ] # unconditionally true
  • if [ -f  / ] # always false

I will experiment with

  • if true; then … # true returns 0 to indicate success
  • if false; then …

Locate msg]binary feed #multiple issues solved

Hi guys, thanks to all your help, I managed to locate the very first trading session message in the raw data file.

We hit and overcame multiple obstacles in this long “needle search in a haystack”.

  • · Big Obstacle 1: endian-ness. It turned out the raw data is little-endian. For my “needle”, the symbol integer id 15852(in decimal) or 3dec(in hex) is printed swapped as “ec3d” when I finally found it.

Solution: read the exchange spec. It should be mentioned.

  • · Big Obstacle 2: my hex viewers (like “xxd”) adds line breaks to the output, so my needle can be missed during my search. (Thanks to Vishal for pointing this out.)

Solution 1: xxd -c 999999 raw/feed/file > tmp.txt; grep $needle tmp.txt

The default xxd column size is 16 so every 16 bytes output will get a line break — unwanted! So I set a very large column size of 999999.

Solution 2: in vi editor after “%!xxd -p” if you see line breaks, then you can still search for “ec\_s*3d”. Basically you need to insert “\_s*” between adjacent bytes.

Here’s a 4-byte string I was able to find. It span across lines: 15\_s*00\_s*21\_s*00

  • · Obstacle 3: identify the data file among 20 files. Thanks to this one obstacle, I spent most of my time searching in the wrong files 😉

Solution: remove each file successively, starting from the later hours, and retest, until the needle stops showing. The last removed file must contain our needle. That file is a much smaller haystack.

o one misleading info is the “9.30 am” mentioned in the spec. Actually the message came much earlier.

o Another misleading info is the timestamp passed to my parser function. Not sure where it comes from, but it says 08:00:00.1 am, so I thought the needle must be in the 8am file, but actually, it is in the 4am file. In this feed, the only reliable timestamp I have found is the one in packet header, one level above the messages.

  • · Obstacle 4: my “needle” was too short so there are too many useless matches.

Solution: find a longer and more unique needle, such as the SourceTime field, which is a 32-bit integer. When I convert it to hex digits I get 8 hex digits. Then I flip it due to endian-ness. Then I get a more unique needle “008e0959”. I was then able to search across all 14 data files:

for f in arca*0; do

xxd -c999999 -p $f > $f.hex

grep -ioH 008e0959 $f.hex && echo found in $f


  • · Obstacle 5: I have to find and print the needle using my c++ parser. It’s easy to print out wrong hex representation using C/C++, so for most of this exercise I wasn’t sure if I was looking at correct hex dump in my c++ log.

o If you convert a long byte array to hex and print without whitespace, you could see 15002100ffffe87600,but when I added a space after each byte, it looks like 15 00 21 00 ffffe876 00, so the 3rd byte was overflowing without warning!

o If you forget padding, then you can see a lot of single “0” when you should get “00”. Again, if you don’t include white space you won’t notice.

Solution: I have worked out some simplified code that works. I have a c++ solution and c solution. You can ask me if you need it.

  • · Obstacle 6: In some cases, sequence number is not in the raw feed. In this case the sequence number is in the feed, so Nick’s suggestion was valid, but I was blocked by other obstacles.

Tip: If sequence number is in the feed, you would probably spot a pattern of incrementing hex numbers periodically in the hex viewer.

scan entire codebase4given func name #how2

–Challenge: scan a c++ codebase for a given func name

  • A script would offer more flexibility.
  • find + perl + grep is a crude solution, without support for comments

See also the task in Outlook!

–A related challenge: suppose you have the definition of a function, how do you see all the callers?

Csmi.C: In static member function ‘static csmiparser::Csmi& csmiparser::Csmi::getInstance()’:
Csmi.C:14: warning: ‘__comp_ctor ’ is deprecated (declared at /home/vtan/tp/plugins/xtap/csmi/include/Csmi.h:33)

  • Technique — Rename the by appending _xxx and rebuild


msol mailbox folder size limit

A corporate Exchange server allocates typically 100MB for your account, covering
– data in your calendar
– data in your sent items

NOT covering
– archive folders (usually on your PC)
– personal folders (usually on your PC)

— To investigate
Choose your mailbox (or archive / personal folders) -> right-click -> properties -> folder size
Choose your mailbox (or archive / personal folders) -> right-click -> properties -> Advanced You can see storage locations.

— to “shrink” your data
choose your mailbox -> right click -> advanced find -> more choices -> size greater than 999KB -> advanced tab -> choose Received -> on or before -> 2008/12/31 or 2008-12-31 formats

You can
– remove attachments and add a comment [attachment removed tanbin 9feb]
– permanently delete them or
– move them into personal folders on your PC

c++timestamp string includ`microsec

        struct timeval timeValNow;
        gettimeofday (&timeValNow,NULL); //populates the struct
        struct tm * ptm = gmtime( &timeValNow.tv_sec );
        timestampNow<<ptm->tm_year +1900;

## tips: search in q[less]

  • after you have searched for “needle1”, how do you expand on the pattern? You can hit 2 keys
    • [2]  /↑ (i.e. <upArrow>) to load “needle1.” Now you an edit it or add an alternative like
    • [2+]/↑ (i.e. <upArrow>) |needled2|needle3
  • In a q(less) screen, You can highlight not only the same AAA occurrences, but AAA or BBB. I used


  • [2/3] /ctrl-R — search without metacharacters
  • -i, then /needle — case insensitive

[3/4] means vi/less receives 3 keystrokes; we hit 4 keys including shift or ctrl …

–search can fail with super-long lines. See also

  • Symptom — if you navigate to the correct region of the big text file, then the search does hit the target word.
  • Solution — use grep to confirm


win10 system+user settings GUI

I prefer the controlPanel rather than the Settings screen… ControlPanel can show all the apps without the messy categories. Also, the winKey->search is unreliable when searching for a controlPanel app. Once again, Microsoft did a sloppy job.

To change any setting, I believe we always need one of those apps. Windows GUI try to hide the boundaries between the apps, and make it very very confusing.

linux command elapse time

–q(time) command

output can be a bit confusing.

Q: does it work with redirection?

–$SECONDS variable

DOS replacement, again


not yet tested

–%% wishlist
edit command history
shell integration

🙂 conEmu can search throughout console output
🙂 conEmu here
🙂 conEmu double-click to select text
🙂 console2 requires research (no time!) on tweaking to fix copy/paste.
🙂 console2 here
😦 PowerCmd requires admin right every time to use

bookmarking in vi

— based on

Any line can be “Book Marked” for a quick cursor return. Type the letter “m” and any other letter to identify the line. This “marked” line can be referenced by the keystroke sequence “‘” and the identifying letter.

Example: “mt” will mark a line by the identifier “t”. “‘t” will return the cursor to this line at any time. I prefer mm and ‘m

A block of text may be referred to by its marked lines. i.e.’t,’b

set up dependency between two c++ projects

I will mostly talk about MSVS but will mention linux build too.

The common methods to set up the dependency, all done inside project BB

1) specify project dependency in MSVS

2) define include path to cover the header from AA

3) define library path to cover the object file from AA

Suppose project BB uses “things” in project AA. Say a file in BB #-includes a header in AA. I think it's not necessary to have any. This is important when you debug the dependency. You may fail to find any trace of the dependency in any of those places. The file in BB can simply #-include the full/relative path to the header from AA. describes project reference vs project dependency….

….. much more to say.

q[screen] command cheatsheet

For each feature, let’s verify it and give links to only good web pages

Even after the “parent shell” of the screen is killed, the screen is still alive and “attached”!

–[ Essential] How to tell if I’m in a screen

echo $STY

–[ Essential ] reattach

— [ Essential ] list all child screens
screen -R # lists all or reattach if only one.
screen -ls # just list

— [ Essential ] detach i.e. put current screen session to the background
Ctrl-A then ‘d’

keep a session alive after I log out. Almost like windows mstsc.exe

–feature – log the screen output
The log file is created in the current dir …

–feature – Run a long running process without maintaining an active shell session
See — using top as a long command

–(untested) feature – monitor a screen for inactivity as a sign of job done.

—– A real example:

Motivation — I need to run some daemon process in “background” but ideally inside a separate container/shell, so I can switch between that environment and my original environment. However, I don’t want to create another putty session. That’s indeed a more “separate” environment, but comes with higher cost like a lengthy log-in procedure.

[in console] screen # to create a new screen
[in screen-1] ./startDaemon # Note the command doesn’t return
[in screen-1] Ctrl-A d #to switch back to console
[in console] screen -ls # shows screen-1
[in console] screen -R # to switch into screen-1
[in screen-1] # now we are back in the running command which has not returned !
[in screen-1] Ctrl-Z # to suspend this stubborn command
[in screen-1] bg %1 # to put the command into proper background of screen-1



trailing comment in DOS batch

set "var=3"     %= This is a comment in the same line=%
dir junk >nul 2>&1 && %= If found =% echo found || %= else =% echo not found
The leading = is not necessary, but I like if for the symmetry.
There are two restrictions:
1) the comment cannot contain %
2) the comment cannot contain :

[15] %% bashrc


<![CDATA[ << ______________end_of_comment_1________________ J4 etc: to reduce section spacing modified [11 Jan 2007] ______________end_of_comment_1________________ [ -z “$(echo $- | grep i)” ] && return # # # # # # # # # # # # # # # # # # # # <> should be first # # # # # # # # # # # # # # # # # # # # # # # export PS1=’\n\s!\! \u@\h [ \t \d ] \w/ \n\$ ‘ export EDITOR=vi # primarily for sqlplus export EXINIT=” :se nu | :map v :w ” # must export LESS=”–ignore-case” export TMOUT=987654; [ $root ] && export TMOUT=100600 HISTSIZE=900 set -o emacs set +o nounset export PATH=/usr/xpg4/bin:$PATH; [ $(id -u) = 0 ] && root=yesur set +o noclobber; [ $root ] && set -o noclobber sav=$LOGNAME # # PAGER and TERM issues: # # “vt100 less -E” is ok on linux # TERM ‘linux’ breaks vi in gnome-terminal; ‘linux’ imperfect for solaris # for “less”, -E needed for dir-viewing, file-viewing but affects man # export PAGER=more export PAGERE=more if [ -z “$(which less |grep ‘^no less’)” ]; then export PAGER=”less” # breaking some x terminals but ok in “console” export PAGERE=”less -E” # -E needed for dir-viewing, file-viewing but affects man fi echo TERM=$TERM initially export TERM=vt100 # ‘linux’ breaks vi in gnome-terminal; ‘linux’ imperfect for solaris # # # # # # # # # # # # # # # # # # # # # # # # <># # # # # # # # # # # # # # # # # # # # # # # alias killthem=”perl -pe ‘s/^\S+(\s+\d+).*/\1/ or s/.*//’|xargs -pt kill” # p str1 | killthem # alias killthem=”perl -pe ‘s/\S+(\s+\S+).*/\1/s’|xargs -pt kill” # p str1 | killthem # sortable : alias %=cd_l # typing trainer alias ..=’cd_l ..’ alias cp=’cp -i’ # defuse alias egi=’export |grep -i’ alias h=history alias hgi=”history |grep -i” alias j1=”fg %1″ alias j2=”fg %2″ alias m=$PAGERE alias mv=’mv -i’ # defuse alias p=ps_grep alias path=” echo \$PATH |perl -pe ‘s/:/\n/g’ |sort -u|m ” alias rm=myrm alias s=’ source $HOME/.bashrc ‘ # .profile absent alias t=’l -t’ alias top=’prstat’ # # # # # # # # # # # # # # # # # # # # # # # # <> difficult to sort # # # # # # # # # # # # # # # # # # # # # # # cd_l(){ [ $# -eq 0 ] && l && return [ -n “$( file $* | grep directory )” ] && cd $* && l && return [ -n “$( file $* | perl -ne ‘print if /text|script/’ )” ] && m $* && /bin/echo “\n\n” && l $* } d(){ [ $# -ne 0 ] && cd $* [ `pwd` = ‘/’ ] && target=/ && echo I am in / echo “In MB :” eval du -ks * |sort -n|perl -pe ‘s|^(\d+)|$1/1000|e’ } g(){ # bug with g -v pattern=$1; shift cmd=” grep -i \”$pattern\” $* ” /usr/bin/printf ‘%s\n’ “cmd=__$cmd __” eval $cmd |$PAGERE } l(){ # can’t be completely replaced by ‘cd_l’ or ‘]’, because “cd_l -tr dir1″ is confusing and should be avoided /bin/ls -alFs $* |$PAGERE } myrm(){ cmd=”mv -i $* /var/tmp/$sav/ ” /usr/bin/printf ‘%s\n’ “cmd=__$cmd __” eval $cmd } ps_grep(){ ## cmd1=’/bin/ps -ef’ # truncation risk # ps auxwww : inconsistent for root vs non-root cmd1=’/usr/ucb/ps auxwww’ # |grep -v grep — no cos some real commands contain grep for f in $*; do cmd1=”$cmd1 | g $f” done eval $cmd1 } sav(){ suffix=$RANDOM$(date +”%H%d%b”) # to avoid misleading readers,make the suffix ambiguous for f in $*; do f=$(echo $f|perl -pe ‘s|/$||’) # sav dir/ b=`basename $f` ( cd `dirname $f` ; tar cf – $b | (cd /tmp; tar xpf -) /bin/mv -i /tmp/$b $b.b4${sav}edit$suffix [ -d $f ] && opt=’ -d’ eval ls -lt $opt $b* ) done } # # # # # # # # # # # # # # # # # # # # # <>, an exercise in grouping # # # # # # # # # # # # # # # # # # # # # # # exa(){ #testing: exa -t ss ~/.ssh local ops while is_opt=`echo $1 |perl -ne ‘print if /^-/’ ` && [ “$is_opt” ]; do ops=”$ops $1″; shift done if [ $# -eq 1 ]; then fullpath=$1 shortname=`echo $1|perl -pe ‘s|/$||;s|^.*/||’ ` else fullpath=$2 shortname=$1 fi [ -x $fullpath ] || return # export “$shortname”=”$fullpath” set $shortname=”$fullpath” prj=”$fullpath” alias “$shortname”=”cd $fullpath;l $ops” alias prj=$shortname # USE MORE } exa /tmp/ exa /etc # # # # # # # # # # # # # # # # # # # # # <># # # # # # # # # # # # # # # # # # # # # # # add_path(){ [ -r $1 ] || return [ “$(echo $PATH|grep :$1)” ] && return # check world write perm, esp for root PATH=$PATH:$1 } set_manpath(){ # very slow on some systems. Run this when u need it. for d in `ls -d /[uo]*/*/man /[uo]*/*/*/man /[uo]*/*/*/*/man`; do export MANPATH=$MANPATH:$d done } set_path(){ add_path /usr/sbin add_path /usr/bin add_path /sbin add_path /usr/local/bin add_path /usr/cluster/bin add_path /usr/openwin/bin/ add_path /usr/ucb add_path $ORACLE_HOME/bin add_path /usr/sfw/bin # pre-installed add_path /opt/csw/bin [ $root ] && return add_path . add_path $HOME/bin } set_path ]]>

DOS | Temporarily change working directory for a single command

pushd myjava & java -Djava.rmi.server.codebase= -classpath %CP% 19673  & popd


This DOS command line does 3 things

1)      temporarily chdir into “myjava” folder and

2)      run a (long) java command line, and then

3)      restore the previous directory.


Actually, the java process blocks the script forever. If you use ctrl-C to terminate the blocking java process, you still get back into the previous directory J




log4net line number (%line) requirements

If you don’t satisfy all the conditions, then you get “0” as the dummy line number.

1) deploy the pdb files of all of my own DLL and EXE. If you put in some of them you may see some line numbers.
2) pdb file and the DLL/EXE should come from the same build. Version mismatch will trigger no exception. Just “0”.

Obviously you need something like this to see any logging at all —


get class file physical location of a java object #home made

<![CDATA[ private static String getMetaData4Obj(Object o) { return getMetaData4Class(o.getClass()); } private static String getMetaData4Class(Class clazz) { String className = clazz.getName(); className = className.replace(“.”, “/”); className += “.class”; URL location = clazz.getClassLoader().getResource(className); return clazz + ” loaded from ” + location; } ]]>

c# programmatically retrieve file path of runtime objects

From a Method object you can get the host Type object.

From a Type object you can get the host Assembly object.

From Assembly object you can get the physical assembly file.

1) (tested) Assembly.GetExecutingAssembly().Location; // gives the dll fullpath
1c) new T().GetType().Assembly; //returns the Assembly object. Works even though T is a template dummy type!

2) Process.GetCurrentProcess().MainModule.FileName

3) AppDomain.CurrentDomain.BaseDirectory; // Similar to 1)

c# regex-match backslashes in strings

My suggestion — First find a “safe” character that’s guaranteed not to show up in the original string, like “_”. Replace all back slashes. Then proceed.

Problem with backslashes is the unnecessary complications. Here I want to match “one-or-more backslashes”. In the end I need to put 4 bachslashes in the pattern to represent that “one”.

var ret = Regex.Replace(@”any number of\\\backslashes”, “(.+\\\\+)?(.+)”, “$1 – $2”);

Alternatively, I could use @ to reduce the complexity @”(.+\\+)?(.+)”

Disappointingly the @ does a partial job. We still need 2 strokes — Confusing! I’d rather just remember one simple rule and avoid the @ altogether

%errorlevel% in DOS, briefly

Errorlevel is like a “dynamic readonly” whiteboard (NOT an environment variable — see below). The whiteboard is wiped clean and overwritten by DOS after each command executed. This happens whether you run the commands interactively or in batch using *.bat files.

You can say this whiteboard shows _transient_ values. For a crude analogy, consider the variable behind LED temperature display. It keeps changing.

If you want to capture a particular transient value of this object, save it *immediately* in your own variable (before echoing %errorlevel%). See

A: %ERRORLEVEL% will expand into a String representation of the current value of ERRORLEVEL, provided that there is not already an environment variable with the name ERRORLEVEL, in which case you will get its value instead. 
A: To see the value, you must use %xxx%. Consistent with other DOS variables such as %OS%

&& and || together

[ -f unixfile ] && rm unixfile || print “unixfile was not found, or is not a regular file” — to be tested

Finally, multiple commands can be executed based on the result of command1 by incorporating braces and semi-colons:

command1 &

If the exit status of command1 is true (zero), commands 2, 3, and 4 will be performed.

See other post(s) on exit status

perl one-liner : sum across lines

A common perl-n/perl-p challenge is to sum over loops. Solution is the END{} block.

This example below is from

ls -lAF | perl -ne ‘   next if /^d/; $sum += (split)[4]; END{ print $sum }   ‘

(I guess this sums up all the files’… sizes?)

Note you need not pre-declare $sum as a static-local (in C lingo). I guess it’s static-local by default.

was my unix cmd successful@@

This post focuses on one question:

Q: was previous cmd successful@@
A: (based on [[ teach yourself shell programming ]])

if [ $? -eq 0 ] ….

Background: i wasn’t sure if my own solutions were reliable. Now this author also believed in [ $? -eq 0 ]

cmd1 && … # tests 0. [[ learning the bash shell ]]
cmd1 || .. # tests 0.

“0 means OK” is standard convention. A script or command can break the convention, but you are allowed to assume no one does.

custom logger to show src line num, caller, parent caller and grandparent caller

<![CDATA[ /** based on* Class name is mentioned in C:\Program Files\Java\jre1.6.0_06\lib\ */ public class JDKLoggingForamtter extends SimpleFormatter { private final String lineSeparator; public JDKLoggingForamtter(){ lineSeparator = new“line.separator”)); } @Override public synchronized String format(LogRecord record) { String sb = super.format(record); String lineNum = getEclipseFormat(); return sb.replaceFirst(lineSeparator, ” ” + lineNum + lineSeparator); } /** * Returns caller location information in eclipse format eg ( * WARNING Generating caller location information is extremely slow. * It's use should be avoided unless execution speed is not an issue. * * @return the eclipse format */ private static String getEclipseFormat() { // getStackTrace can be expensive StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); String upstairs = “”; int lineNumber = 0; //StringBuilder sb = new StringBuilder(); // Here is an example of the typical stack trace we get back. // level 0 ( getStackTrace // level 1 ( getFileLineNumber // level 2 ( format // level 3 ( publish // level 4 ( publish // level 5 ( log // level 6 ( doLog // level 7 ( log // level 8 ( someMethod if (stackTrace.length >= 9) { String fileName = stackTrace[8].getFileName(); lineNumber = stackTrace[8].getLineNumber(); // Each of these calls back into logger.logp with the appropriate // level and message. This adds one extra level to the stack trace // logger.finest(“finest message”); // logger.finer(“finer message”); // logger.fine(“fine message”); //“info message”); // logger.warning(“warning message”); // logger.severe(“severe message”); // logger.entering(“SomeClass”, “aMethod”); // logger.exiting(“SomeClass”, “aMethod”); // logger.exiting(“SomeClass”, “aMethod”, “returnval”); // logger.config(“config message”); // // Here is an example stack trace from a call to exiting // level 0 ( getStackTrace // level 1 ( getFileLineNumber // level 2 ( format // level 3 ( publish // level 4 ( publish // level 5 ( log // level 6 ( doLog // level 7 ( logp // level 8 ( exiting // level 9 ( someMethod // // We could check the name of the method we are in and only go one level deeper // if it is one of “finest”, “finer”, “fine”, “info”, “warning”, // “severe”, “config”, “entering” or “exiting” but that would be too much trouble. // If the stack is in and we can go one level deeper – do it. if (stackTrace.length >= 10 && “”.equals(fileName)) { fileName = stackTrace[9].getFileName(); lineNumber = stackTrace[9].getLineNumber(); } if (stackTrace.length >= 10){ upstairs = ” = 11){ upstairs += “

pushd popd – G5 tips

  • pushd dirA ###  1) push current dir, 2) push dirA, 3) Enter (i.e. cd into) dir1 i.e. the new top
  • popd ### without arg — means 1) pop 2) Enter the new top in the stack. I guess the item “removed” is forgotten completely.
  • pushd ### without arg — means 1) swap top two on the stack. 2) “Enter” (i.e. cd into) new top
 –Gory details
### I feel top item is always, always kept in sync with current dir. An understanding of the stack is essential. The stack is shared by cd, pushd, popd.
  • cd – ### a single dash — means “Enter” previous directory (in history, not the stack). Overwrite top.
  • pushd +2 ### means 1) identify the 3rd (not 2nd) on the stack. Rotate it to top. 2) Enter new top
  • cd dir1 # replace top item on the stack with dir1
  • dirs -v # print stack. Readonly operation.
  • popd +2 # identify the 3rd (not 2nd) on the stack and remove it. Don’t change current directory, since top is unaffected.
  • popd +0 # Probably pop the top. Enter the new top.

q{FIND} | perl,grep,notepad++

q(grep -r –color) is a simple solution but I still worry about lack of control.

# use grep inside perl, without xargs
find . -type f|perl -nle 'print "$_ --\n$a" if /\.(C|h)/ and $a=qx(grep -i "btmodels" "$_") '
find . -type f|perl -nle 'print "$_ --\n$a" if !/\.git/ and $a=qx(grep -i "btmodels" "$_") '

MSWE search is unreliable for full-text search. Ditto for MSVS search. Don’t waste time on them!
Try notepad++. You can click the search result, and get keyword highlight, like in google!
Try findstr in

exceed copy-paste between win32 and X-windows

Using exceed, it can be a challenge to set up copy-paste between win32
and X windows. I know 2 options.

Note I always enable auto-copy-x-selection and

— option: X-selection-page -> X Selection Associated With Edit
Operations set to Primary —
Lesson? “Primary” is the default. In this mode, don't use the xwin

* Simple-Select (without middle-button or context menu) to copy from
unix, paste to win32? Yes
* Simple-Select (without middle-button or context menu) to copy from
unix, middle-button to paste to unix? yes
* Select from win32, middle-button to paste in unix? Yes
* Select from win32, context-menu->edit->paste in unix? no

— option: X-selection-page -> X Selection Associated With Edit
Operations set to Clipboard —
This is suggested on some webpage. It also enables copy-paste between
unix and windows. – replacing StringBuilder

In most cases, I can replace StringBuilder with a Formatter, but of course Formatter offers more!

new Formatter(new StringBuilder()) painlessly appends!

import java.util.Formatter;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;

public class FormatterTest {
    private Formatter formatter;
    private StringBuilder sb;
    public void setUp() {
        this.formatter = new Formatter(new StringBuilder()); = new StringBuilder();
    public void testArray() {
        char[] var= new char[] {‘a’, ‘b’, ‘c’};
        formatter.format(var+””, “”);
        assertEquals(sb.toString(), formatter.toString());
    public void testInt() {
        int var=902;
        formatter.format(var+””, “”);
        assertEquals(sb.toString(), formatter.toString());
    public void testFloat() {
        float var=902;
        formatter.format(var+””, “”);
        assertEquals(sb.toString(), formatter.toString());

java getResourceAsStream() – easist(@@) way to read any file

You can easily read a file in the same dir (esp. in a jar) as your class or anywhere(?) on file system. Methods below are usually conveniently called on the Class object, like

1) simplest usage:
InputStream is = this.getClass().getResourceAsStream(“any file such as a.txt”);
InputStream is = AnyClass.class.getResourceAsStream(“any file such as a.txt”);

InputStream is = GetResourceTest.class.getResourceAsStream(“../../test.txt”);
if (is==null) System.err.println(“file not found”);

Behind the scene, these methods delegate to the classloader’s getResourceAsStream() has good examples.

putty — save host-specific config

A host-specific config is saved in a so-called saved-session. To access the list of saved-sessions, go to, paradoxically, _New_Session.._

To see or modify a particular saved-session, you must first Load it. You may need to hit Load several times. Once you are in the “editor” mode on a saved-session,

  • * Navigate to a particular tree branch, like Window
  • * change a particular value there
  • * There’s no Save button. You must navigate back to the original Session page, and hit Save (repeatedly:). This Save button
    ** saves all the settings in the editor
    ** saves them under the session name.
  • * If a parameter has an unsavable value, system will _silently_ drop the change and rollback. seems to be a good FAQ for this.

How about the config file for each connection? Apparently putty uses registry…

–DefaultSettings as a template: save it if you repeatedly use this template.

launch -> select DefaultSettings -> LOAD -> change any setting -> come back and (click to) highlight DefaultSettings -> SAVE

file descriptor redirection, exec

–Annotations on

bash$ lsof -a -p $$ -d0,1,2
bash 363 bozo 0u CHR 136,1 3 /dev/pts/1
bash 363 bozo 1u CHR 136,1 3 /dev/pts/1
bash 363 bozo 2u CHR 136,1 3 /dev/pts/1

bash$ exec 2> /dev/null
bash$ lsof -a -p $$ -d0,1,2
bash 371 bozo 0u CHR 136,1 3 /dev/pts/1
bash 371 bozo 1u CHR 136,1 3 /dev/pts/1
bash 371 bozo 2w CHR 1,3 120 /dev/null <— shows —

exec 6>&1 # Link file descriptor #6 with stdout.
# I think this creates a new file descriptor FD#6 as alias of FD#1. FD#6 is probably a **pointer** to the in-memory object FD#1. The object IS the original file descriptor.

exec > $LOGFILE 2>&1 # stdout replaced with file “logfile.txt”.
# the object is not discarded. FD#6 still points to it, but the current process no longer uses that object.

#### this is a useful thing to put into your script, if someone calls your script.

# now the current process will use the original “object” from now on.
exec 1>&6 6>&- # Restore stdout and close file descriptor #6.

unix subshell — tips

To run a group of commands in a subshell, enclose them in parentheses. You can use redirection to send input to the subshell's standard input or to send its *collective* output to a file or a pipeline.

Since the subshell environment is a duplicate of its parent, it inherits all of the variables of the parent. But the parent shell never sees any changes that are made in the subshell environment, and the subshell, in turn, never sees any changes that are made in the parent *after* the subshell is spawned.

To save return code of a command (among many) from a subshell,

echo $? > /tmp/hamper1390848908.$$
# other commands….
) > ${LOG_FILE} 2>&1
read GMI_RET_CODE </tmp/hamper1390848908.$$

Here's a simpler alternative

## any other command
[ $javaStatus -ne 0 ] && exit $javaStatus
) > ${LOG_FILE} 2>&1
echo $subshellStatus
exit $subshellStatus

bash – test a command is available

Based on [[ teach yourself shell programming ]]
Background — i was looking for a 1)reliable and 2) efficient solution.

type yourCmd > /dev/null 2>&1
echo $? #### should always echo a zero (ok) or non-zero (nok)

type cd > /dev/null 2>&1 && echo ok
type cdddd > /dev/null 2>&1 || echo nok

These were tested personally but some readers (see comment below) reported they don’t always work.

how to instantiate a new java Date object

Q: how to instantiate a new java Date object with 3 numbers for year, month and date?

I guess Calendar could be one standard solution, but not a one-liner.

Practical solution for the time being: use the deprecated constructors

— new java.util.Date?

Only deprecated constructors do that.
java.sql.Date.valueOf(“2008-04-02” )

–new java.sql.Date?

Only deprecated constructors do that.
java.util.Date.getTime() can feed a long to a java.sql.Date() constructor

exit status, if/while, test, &&, ||

I think most if not all shell boolean-constructs evaluate an exit-status. Here are an incomplete list of boolean-constructs — ie constructs about yes/no. Unifying them all, the 2 unifying factors are boolean and exit-status, right?

autosys failure/success? yes
the shell’s IF construct? This is the simplest, base case.
WHILE? same as IF
TEST? same as []
[]? yes. IF [ something ] evaluates the exit status of [ something ]
&& , || ? yes

See other post(s) on exit status

see major.minor versions of a classfile says : Just open the class file with something that can display hexidecimal data and look at bytes 5 – 8 in the file. They contain the minor:major versions in hex.

I used textpad and saw 2E ie 48 for major version. javap reported 0 and 0.

vi corrupting your file

I once had a strange feed file. If I use vi to delete any line, the feed can no longer be processed by the feeder system. I suspect once vi write the file back to disk, it’s corrupted.

Solution: In my case split -1 and head -1 can do a good enough job of deleting lines. Both keep the feed file in good condition.

Q: is vi designed to edit a binary file?

Q: can perl keep all unaffected lines unaffected?

Acid test: less can show the unprintable characters and shows that after deleting one line, every other line has something missing.

q[SET]^q[EXPORT]^plain assignment #no-arg SET

(Not sure about csh. Let’s focus on /bin/sh and bash for now. I bet everything here also applies to ksh.)

“set” is mostly used to set options. I see it less often used to manipulate variables, which is possible but unnecessarily complicated. In fact

set a=1; echo $a # shows nothing

  • “set” alone displays variables, but “set” doesn’t modify/create variables. [1]
  • “export” has a single meaning and you see it used consistently (whereas “set” isn’t).

Are you managing variables in bash? A simple “binary” advice is
– use export for ENV variables
– use “nothing” to manage shell variable — Nothing but “a=1”

How about “let”? Only needed for arithmetic. I would say don’t let this stranger join the club and confuse yourself.

[1] In DOS, “set” command creates variables (

perl one-liners for xml

based on

Find all section titles in a DocBook XML:

# cat files/mybook.xml | xpath //section/title

Retrieve just the significant text (not including nodes containing all-whitespace) from a given document:

# cat files/mybook.xml | xpath “//text()[string-length(normalize-space(.)) > 0 ]”

Save the entire data stored in the ‘users’ table as a huge file users.xml:

# -sn myserver -driver Oracle -uid user -pwd seekrit -table user -output users.xml

Pretty-print a bad xml file:

# cat overwrought.xml | xmlpretty > new.xml

Use the built-in HTML parser to convert ill-formed HTML to XML before further processing:

# xmllint –html khampton_perl_xml_17.html | xpath “//a[@href]”


bash search`unix command #precedence

Q: what if you have an alias, a shell func, a shell built-in (like “echo”), a unix executable file, and your own script all sharing the same name?

Focus on 2 simple rules for now:

1) Your own aliases override everything else (such as shell functions)

2) $PATH is the very last (after things like shell built-in commands) place searched by the shell. Executables in $PATH are external to the shell.

I think the same precedence holdes for any shell.

easiest way to compare 2 files in a windows box

I wanted to compare the old version of with a new version but the two files live on 2 drives.

Now I just browse to the first, right click to mark it for “compare later”. Then i browse to the 2nd file, and right click to compare them.

Immediately the 2 files are loaded in a GUI side-by-side with differences highlighted in color. You can scroll both panes at the same time.

More visual/convenient than WinDiff or CVS-diff in Netbeans.

* The GUI tool is winMerge (
* The WinExplorer context-menu plug-in is Diff-ext (

Diff-ext also lets u compare 3 files or directories.

StringBuffer / StringBuilder offers no prepend()

Use insert(). Example —

   myStringBuffer.insert (0, “prefix string”); // C# and java are similar. See API links below

This technique is rather important to job interview coding tests. (I encountered this in the ITA 50 billion quiz)

Warning — points out that prepend is often less efficient as append

myBuf.insert(5, …) means “insert after 5“, that is, insert after first 5 characters of myBuf.
myBuf.insert(0, …) means insert after 0 character, which is the geeky way of saying prepend — faster but thread unsafe

log4j.xml quick guide

q: threshold?
A: The “threshold” attribute takes a level value such that all
logging statements with a level equal or below this value are

Q: root?
A: root of the xml tree is CATEGORY, which typicall references
1 or more appenders, 2nd level node in the xml tree.

Q: eg@appenders?
A: console, snmp, syslog,

q: log4j.xml changes need restart?
A: no

Q: category vs logger?
A: say “category” in xml; say “logger” in src code
#1 tip: child logger inherits from parent logger

Q: Category names are FQCN?
A: yes. “Engine” shown in console but “com.domain.Engine” shown in log file.