Saturday, October 6, 2012

.bashrc, .bash_profile

While I've learned some nice bash tricks during the past few months, I haven't really gotten to customizing it or really understanding how it works from the bottom up. .bashrc and .bash_profile, for example, are two files close to the boundary of my current understanding of bash's structure.

I don't know how they really work just yet, but as I looked for how to implement bash aliases, I bumped into these sample .bashrc and .bash_profile files, which seem to illustrate bash's ample functionality comprehensively. I'll be honest, I haven't really read even five lines of it, but it seems like a super useful bit of text. Here's the link:


The website seems to be the Linux Documentation project, so I doubt it'll be going away anytime soon. (I was considering copy-pasting its contents, but that seems a bit over-paranoid).

Key repeatssssssssssssssssssssssssssss

I bump into this occasionally, but when I do, it irks me. By default on my OS X, if I press and hold the "a" key, instead of getting a long line of a's, I get this little window:


which sucks. If I wanted to type รก, I would've known it in advance and have pressed the special Option-E + A, or configured my keyboard for Spanish-style input, or found it on a web page somewhere and plagiarized it for my shameless personal gain (as I often do for arcane characters like ☮ and  ). If I wanted to type something like

aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

without having to press the "a" key 81 times. I'd much prefer to instead press the "a" key, hold it for 5 seconds, and be done with it. Yes, I could do it on Terminal, but it's slow to switch to another application every time I want a specific kind of keyboard input.

So today I was browsing around, looking for a way to be able to execute binaries on the current directory, from the Terminal, by typing only their names, and not having to type in "./" at the beginning of the line (you know what I'm talking about). I haven't yet found that, but I bumped into this page:

http://mac.tutsplus.com/tutorials/terminal/10-terminal-commands-that-every-mac-user-should-know/

which among other sometimes-useful tips, taught me how to disable that sucky little key-hold window for the Mac OS X GUI:

defaults write -g ApplePressAndHoldEnabled -bool false

To be honest, I have not tested it (it requires logging off and on again), but I see no reason why it shouldn't work. Enjoy!

Saturday, September 22, 2012

Keyboard Lag

Did you know you can make your keyboard lag even less than the Preferences Pane allows you to, in Mac OS X? You can! From Terminal, write:


defaults write NSGlobalDomain KeyRepeat -int 0


Thank you:
http://hints.macworld.com/article.php?story=20090823193018149
!

****
Update (Aug 18th, 2014):

And to reduce the initial key repeat delay, type this in terminal:

defaults write NSGlobalDomain InitialKeyRepeat -int 4
Lower is faster, but the link recommends not setting it below 4. I'm about to try it now! :D
http://superuser.com/questions/363252/how-to-enable-keyboard-repeat-on-a-mac

Tuesday, August 28, 2012

New Terminal Tab in Mac OS X

I haven't really used this for anything, but it seems that interfacing with the GUI through Command Line is a worthy skill to learn.

osascript -e 'tell application "Terminal" to activate' -e 'tell application "System Events" to tell process "Terminal" to keystroke "t" using command down'

In Mac OS X, it will open a new Terminal tab. More specifically, it will send the key combination "Command-T" to the application called "Terminal". I wonder if Terminal needs to be open for this to work.

Anywho, I think I'll come back to this later! And thanks to these commenting dudes:

http://stackoverflow.com/questions/7171725/open-new-terminal-tab-from-command-line-mac-os-x

Wednesday, August 22, 2012

bc threading

bash allows integer arithmetic, but no floating-point arithmetic. It is not uncommon to want to perform floating-point arithmetic on quick 'n dirty command-line scripts. I needed this a few days ago, and I found the handy bc command, which evaluates arbitrary-precision arithmetic and returns it as a neat shell string:

http://www.linuxquestions.org/questions/programming-9/decimal-numbers-in-bash-script-variables-380924/

Later on, I realized that the scripts that included the bc command were taking just as long or longer to run on a few hundred lines of text than a speech-recognition engine took to decode a half-hour audio file (yes, that's a lot. My script was sloooooooow).

I realized then that bc is a full-on interpreter, and that the overhead of starting it up and shutting it down multiple times per text line was awfully time-consuming.

So I googled around a little bit more, and I found a pretty neat way to deal with this problem: Open up bc on a separate process, and communicate with it through FIFOs! It's not straightforward, but it's certainly ingenious (and oh-just-ALMOST-so-very-clean). Most importantly, it speeds up my process a THOUSAND-FOLD!! Or by a lot, anyway.

It's not a one-line procedure - it requires preemptive initialization and some clean-up afterwards. Basically,
  1. Create two temporary FIFO files, one for input, one for output.
  2. Assign numbered streams to the FIFOs.
  3. Start up a background bc process that inputs from one stream, and outputs to the other. Perform the following two steps as many times as required:
  4. Send bc commands to the input stream.
  5. Read the bc result from the output stream.
  6. When you're done playing with bc, send it a "quit" command.
  7. Close both streams.
And you're done!! It'll be soo much faster! Smart guy who wrote this for all of us to usefully utilize in such situations:

Thanks dude!

As he mentions, this nifty little trick can be used with any other interpreters, like perl, php, or python.

For future reference and to avoid future link breakage, I'm copy-pasting his code here:

#!/bin/bash
##
# Make some fifos we can connect to.
##
mkfifo /tmp/bc.in
mkfifo /tmp/bc.out
##
# Attach file descriptors to those fifos.
##
exec 7<>/tmp/bc.in
exec 8<>/tmp/bc.out

##
# Start a single bc process in background and connect our fds to
# it's stdin, stdout, stderr we can use to do all of our math. We can
# do this because bc is an interpreter, with it's own shell.  Using 
# these same methods we can do inline perl/php/python, etc in 
# bash.
##
bc 0<&7 1>&8 2>&8 &

while read numerator denominator
do
  echo "scale=5; $numerator / $denominator" >&7
  read quotient <&8
  # bc errors have ':' in them somewhere.
  if [ "$quotient" != "${quotient//:/}" ; then
      echo "Error: $quotient"
  else
      echo "Answer of $numerator / $denominator is $quotient."
  fi
done

##
# Shutdown our bc process
##
echo "quit" >&7
##
# Close down our file descriptors.
##
exec 7>&-
exec 7<&-
exec 8>&-
exec 8<&-

Monday, August 13, 2012

vi/bash Miscellanea

Today I discovered and exercised a bunch of great things about vi and bash. To celebrate, I will write the most memorable ones here. First vi:
  1. :% - Indicates to execute a command across the range of all lines. It has helped me greatly in my quick file-wide substitutions.
  2. Recording commands: Press q, then any other letter that will identify the custom command, like a. Then perform the exact sequence of commands, insertions, deletions, modifications you want to record, then press q again. Now you have a recorded command!! Press @a (or whichever letter you chose as the command identifier) to execute this sequence of commands again. Or do it many times with N@a!
  3. You can cut/copy/paste not only lines but words and characters in vi. For example, cut the next 7 characters with 7d[RIGHTARROW]. Or copy the current word with yw. And if you have less than entire lines selected, pasting stays in the same line (I used to only cut/copy/paste entire lines in vi).
  4. Redo with Ctrl-r (for those hasty undos!)
  5. Awesome little "up-arrow"-style previous-command recoverers. To see the last vi command you executed: ":[UP-ARROW]". (And navigate with up-arrow and down-arrow, like in bash or in MATLAB). To see the last search string you looked for: "/[UP-ARROW]". To see a list of possible undo's in your file, execute ":undolist". (I haven't actually tried that last one, but it seems too useful to not write).
And now for bash:

  1. I found a way to exercise that the length of a string variable can be obtained through ${#f}, and that the length of an array can be obtained through ${#f[@]}.
  2. I also exercised with bash arrays: define -a arrVariable=($(ls -all)). Notice the parentheses around whatever you're trying to initialize the array with. I believe the string is split and nicely put into the array using the default IFS (internal file separator) delimiter.
  3. I also found an awesome little tool called bc that makes up for the lack of non-integer arithmetic in bash. Basically, this command $(bc <<< "scale=9; $x/5.7") outputs the result of whatever x was divided by 5.7 with 9-significant-digit precision (I think). It's not exactly a built-in solution, but I think it complements bash's capabilities very appropriately. It really hits the spot. I see it like an adjunct floating-point co-processor for bash. It's great! (Notice the <<<, it'll be explained soon).
  4. I also discovered you can identify streams in this manner: 3 < filename. I'm still not entirely certain how input streams are handled, but at least now I know that I can identify them neatly inside bash scripts.
  5. Also, I learned about the triple redirector operator!! (<<<). It's great! For example, before when I wanted to do something like:
while read line
do
    blah
    blah
    moreBlah
done < filename

filename HAD to be an actual filename - it could not be the ad-hoc result of a quick command obtained on the fly. So sometimes weird hacks had to be made to adapt a quick command result into a file stream. But today I learned that if you replace the last line by 

done <<< $(command here, such as ls -all)

it will now work! I often wondered how to bridge that gap between file streams and ad-hoc input streams. Well, this helps a lot to make that happen!

And... that's it. I'm gonna go home because it's past 11PM and I'm still in the office. Bye...

Newlining

As a budding vi, bash, sed, and general Unix-command-line power user, I'm often pleased at the magical powers that these awesome tools provide. There are a few annoyances inherent to this more minimal environment, though, and one of them has been newline manipulation.

The newline is this mystical, elusive, not-always-obvious-on-terminal, cross-platform-incompatible character that permeates a darn large majority of text files out there. It is a natural and almost global exception case for terminal display and for most text-based manipulation commands. As such, I often find myself wanting to collapse or insert newlines, unable to do so in command line, and unelegantly reverting to TextEdit or other GUIs temporarily just to get the job done. I've always trusted that command line provides appropriate tools to deal with newlines, but I have not set out to learn them just yet.

But today I learned one pretty nifty way of dealing with it in vi. I was trying to convert this command I created ad-hoc'ly:


declare -a f=$(cat robots2002_segs.txt); n=9; echo ${#f}; while (( n < ${#f[@]} )); do echo ${f[$n]}; echo ${f[ (( $n + 3 )) ]}; n=$((n+4)); done

into a nicely delineated:

declare -a f=$(cat robots2002_segs.txt)
n=9
echo ${#f}
while (( n < ${#f[@]} ))
        do echo ${f[$n]}
        echo ${f[ (( $n + 3 )) ]}
        n=$((n+4))
done


Seems easy enough, right? Replace the "; " strings with a newline, and I'm (almost) done! But alas, how do I tell vi's substitute (:s) command that I want to represent the newline character, when the key I use to represent it, [ENTER], only tells vi to execute the command?

Well, today I found out! Command down here:

:%s/; /CtrlVCtrlM/g

Break-down:

  • : begins the vi command
  • % tells it to apply this command on all lines of the file (unnecessary in this example)
  • s stands for substitute-command
  • ; / text to be replaced
  • CtrlvCtrlM The magic! Vi's representation for a newline, as far as I can tell.
  • /g Do it as many times as you can.


And done! And then I spent 20 minutes writing the blog post, when doing the whole thing manually would've taken me no more than 20 seconds. Oh, the joys of obsessive optimization!

Credits: (Thanks Mr. Boothe!)
http://www.computing.net/answers/unix/vi-ex-substitute-with-newline/6485.html

Sunday, August 12, 2012

File splitting

Have you ever wanted to email a large file and discovered that it was JUST a bit larger than the maximum allowed file size? Have you ever wanted to copy a 6GB file but only had a 2GB USB flash drive to do it? Have you ever wanted to transfer a 4.7GB DVD image file through your free 2GB Dropbox account, and even considered paying the $5 monthly rate to get the overkill of 50GB limit?

I have. Well, not the Dropbox thing - I got 16GB free because I invited everyone I could when it started :). Even so, one time I couldn't move a 20GB file through.

And just now I'm asking a non-techie to send me a file several GB in size, but her Dropbox account is not large enough. Mine is, but I'm not giving her my password. Oh no! What to do?

So I googled a bit, and sure enough, Unix can solve that problem too! How, you may ask? With split!!

As described by man split:


SYNOPSIS
     split [-a suffix_length] [-b byte_count[k|m]] [-l line_count] [-p pattern] [file [name]]

DESCRIPTION
     The split utility reads the given file and breaks it up into files of 1000 lines each.  If file is a single dash (`-') or absent, split reads from the standard input.


So, say you have a file called IMG_4625.JPG that is around 3MB large:

3009327 Aug 12 00:05 IMG_4625.JPG

and for some reason you want to split it into files only 500K each. You can do:

split -b 500k IMG_4625.JPG 


This will create the following files:


512000 Aug 12 00:09 xaa
512000 Aug 12 00:09 xab
512000 Aug 12 00:09 xac
512000 Aug 12 00:09 xad
512000 Aug 12 00:09 xae
449327 Aug 12 00:09 xaf

When they are in this form, you can transfer them however you want. To put them back together, you just say:

cat x* > IMG_4625.JPG

And voilร , you have your file back! Easy, huh? Extra options are available through the man file.

Credits (thank you!):
http://stackoverflow.com/questions/2016894/easy-way-to-split-a-large-text-file

Thursday, August 2, 2012

Command Line Copy/Paste

At times I find myself grabbing and copying some text from a GUI editor, and wanting to save it all into a file somewhere for command line access and manipulation (e.g. log files). My usual approach used to be one of the following (numbers in parentheses are the number of keystrokes used):
  1. Open Spotlight(2); Open TextEdit(2+O(1)+1); [PASTE](2); [SAVE](2); type in the new filename(N); Select WITH THE MOUSE to save it as a plain text file and NOT as an RTF as is TextEdit's freaking default setting, and click SAVE(3 mouse seeks, 3 clicks!); Close TextEdit(2 or 4, I close the window first with Command-W before Command-Q to avoid the file re-appearing when I open TextEdit the next time); Move this file to where I want it through Terminal. (O(N)). At least 15 keystrokes AND 3 mouse seek+clicks - it's a freaking long process for a task so punctual.
  2. type "vi <filename.txt>" in Terminal(4+N); Press "i" to enter INSERT mode(1); [PASTE] the contents(2); ESC, Save and Exit with ":wq"(6). 13+N keystrokes in total, much better considering the mouse is never needed.
The second option sounds way better, although sometimes when I copy some text many MB long, vi dutifully attempts to load it all up into memory and display it for me on the screen. This can take a while, plus for especially lengthy texts, it encourages dreaded pagination to kick in.

So I Googled around for a bit and found two shiny little gems that will redeem my inter-Terminal-GUI interfaces (at least on my Mac OS X):
  • pbcopy < inputStream
  • pbpaste > outputStream
As straightforward as they should be. 8+N keystrokes, and no further user interface required. Would be absolutely perfect to automate GUI tasks, if I knew how to handle GUI's from the command line in detail.

Credits where credit's due:

Friday, July 27, 2012

Command-Line Media Conversion

Tired of searching for those ever-changing media converter applications, or for an online conversion site that is actually working at any one time?

Search no more!! Install ffmpeg (and sox too) and learn how to convert media from most formats into most other formats... easily-peasily!

Common usage:

ffmpeg -i input.mp4 out.mkv
Done! Give it whichever input file in any format, tell it which file to output to (with the appropriate extension), and press [ENTER]! You'll have your toasty new file in a few seconds, minutes, hours, days, months, or years, depending on your computational power, file size, network speed (if applicable). Most likely a few seconds will suffice. Convert AVI-MP3, MP3-WAV, AVI-MKV, MOV-AVI, MKV-MP3, MOV-AIFF, or whatever you want! (Just make sure it makes sense - you can get audio out of video, but most probably not the other way around).

Also consider sox, an audio-specialized application with a wider spectrum of formats, precise control over channels, sample rates, dithering, and many other audio-specific attributes, effects, and synthesizers, plus other great tools like direct file playing and recording:
  • Play a music file: play musicFile.mp3
  • Recording yourself into a wave file: rec myRecording.wav
  • Convert all the .raw files in your current directory to wave files: for f in *.raw; do sox -r 16000 $f ${f/.raw/.wav}; done

There ya go! Apply and enjoy! Credits due:

VI Capitalization

Have you found yourself in the need to either capitalize or de-capitalize a large amount of text, and realized that your text editor did not have that capability, so you proceeded to re-type all of your text in your desired capitalization?

Re-type no more!!! vi will save you, as it has save many others so often before!!

  1. Open your file in vi.
  2. To convert all to uppercase, press gggUG
  3. To convert all to lowercase, press ggguG
  4. Done!
Alternatively, you can type in either of these longer vi commands:
  • <ESC>:%s/.*/\L&/
  • <ESC>:%s/.*/\U&/
though surely variations of these allow you much greater flexibility for more precise and/or complex substitutions.
Enjoy!

And of course, credits due to:


http://www.lefred.be/?q=node/75

Thursday, July 26, 2012

Finding/opening your smallest/largest images/files

So I have a folder of about 14K pictures and videos, and I decided to try to find the smallest images in my set (I was actually looking for the darkest ones, and it kinda worked). So I made up this command, and it works out nicely:

open $(find . | grep JPG | xargs ls -all | sed 's/  */ /g' | cut -f 5- -d' ' | sort -nr | tail -n 500 | cut -f 5 -d' ')



Logical steps:
  1. find . : Shows all files inside the current directory, and recursively inside all subdirectories.
  2. grep JPG : Remove all no-JPG files from the list (folders, system files, video files, etc).
  3. xargs ls -all : Re-list all the files, this time with all file attributes (size, permissions, etc).
  4. sed 's/ */ /g' : Replace all space sequences with a single space.
  5. cut -f 5- -d' ' : Grab only the attributes starting from the file size column (this might vary depending on your ls default attributes. Tweak the "5" to accomodate your own settings).
  6. sort -nr : Sort descendingly by file size.
  7. tail -n 500 : Grab only the 500 last files (I didn't want to open ALL of them).
  8. cut -f 5 -d' ' : Grab only the actual filename (remove all other attributes).
  9. open : Open them in Preview! (Or whatever your default image-viewing application is).
  10. View!

Google Web Search Keyboard Navigation

A few days ago, I realized that Gmail has the best keyboard UI among all of the Google products. Its keyboard amenability is a highly desirable feature among users who like performing tasks without frequently switching over to the mouse.

So today I was telling a friend about this, and about how even Google Web Search does not have such a keyboard-friendly interface. I opened a Google Web Search window to demonstrate how one couldn't navigate up and down the searches with "j" and "k", and how one could not open a search result with "o". But then I thought maybe it was navigable with arrow keys. So I tried it, and sure enough, it works!!! Steps here:
  1. Search for something on Google.
  2. Press [TAB] to remove focus from the main search text box.
  3. Press [UP] and [DOWN] to move up and down the search results!
  4. Press [ENTER] to open that search result! This also replaces your current browser tab. OR...
  5. Press [Command]-[ENTER] to open the search result on a new tab! I imagine it works with [Ctrl]-[ENTER] on Windows machines.
Now I'm curious to see what other Google products I can find keyboard shortcuts for. I've noticed Google Play is notoriously lacking in these, but maybe YouTube and Maps have matured to the point of keyboard interactivity.

And... ENJOY!!

Wednesday, July 25, 2012

Bash Pause

How do you pause a bash script, either to prompt a keypress or to actually get some input into the program? Easy peasy, use the read -p command!

Such as:
read -p "Press [Enter] key to start backup..."

Thanks!:
http://www.cyberciti.biz/tips/linux-unix-pause-command.html

Wednesday, June 27, 2012

Folder sizes in Mac OS X Finder

So my hard drive is reaching that point when it feels like I'm stuffing the socks inside the jars to save space. Performance is degraded, typing is slow, and you want to get rid of the useless big files. What do I do? I try to remember where the big files are, and go looking for them sequentially. What if I can't remember about those 200 useless YouTube videos I downloaded that one time, or about that music folder a friend passed me through his USB key and I never listened to? Wouldn't it be nice if the computer could tell you: "Hey, there's this 10Gb bunch of files you haven't used in 2 years - maybe you'd like to clear THOSE up?"

Well, now you can! On Mac OS X finder, anyway. I'm sure this feature's been around for ages, but it's only been a few months since I figured it out, and though it's not handy every day, when it is it saves you a LOT of time.

Finder can show you the size of entire folders. It takes some time to compute and some space to store, I'm sure, but oh yes it can. Steps:

  1. Go to Finder.
  2. View -> Show as List (Or WeirdClover-2)
  3. View -> Show View Options (Or WeirdClover-J)
  4. Check checkbox "Calculate all Sizes", and if unchecked, also check "Size".
  5. Done!
Now you should see the aggregate digital space consumed by everything inside it. Isn't it nice? Sort by the "Size" column, and you should start to free up space really quickly by deleting that folder at the top of the list that takes of 15% of the hard drive (Zipf's Law).

And, enjoy!

Thursday, May 10, 2012

PDF Merge


So I needed to merge PDFs today (to join up a bunch of scattered homeworks), and I found this nice GhostScript command online:

gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=merged.pdf source1.pdf source2.pdf source3.pdf etc.pdf

Works nicely.

Saturday, March 3, 2012

Uninstall MySQL from Mac OS X

Once again, the Mac's loose integration with a lot of software due to its Unix-wannabe attitude causes user-unfriendliness issues. How to uninstall MySQL from Mac OS X?


One Google search finds the following:


sudo rm /usr/local/mysql
sudo rm -rf /usr/local/mysql*
sudo rm -rf /Library/StartupItems/MySQLCOM
sudo rm -rf /Library/PreferencePanes/My*
rm -rf ~/Library/PreferencePanes/My*
sudo rm -rf /Library/Receipts/mysql*
sudo rm -rf /Library/Receipts/MySQL*
sudo rm -rf /var/db/receipts/com.mysql.*
&
sudo vim /etc/hostconfig # and remove the line MYSQLCOM=-YES-


Works well enough for me.

Wednesday, February 29, 2012

Show hidden files, Mac OS X

Mac OS X's Finder annoyingly does not seem to have a GUI option to show/hide hidden files/folders in the file system. But it can be done through the terminal, easily enough:

To show hidden files:
defaults write com.apple.finder AppleShowAllFiles TRUE

To hide hidden files:
defaults write com.apple.finder AppleShowAllFiles TRUE

Not too bad, right? Credits to:

Monday, February 20, 2012

File type count

Say you have a big directory of files spread across tons of subfolders, and you want to find the unique file types present, along with the count for each one. Try this:

find . | sed -e 's/\.[^.]*\.\(.*\)/\1/g' | grep -v '^\.' | sort | uniq -c > ~/files3.txt
  • find lists all the files across all subdirectories.
  • sed grabs only the extension after the . in each filename.
  • grep removes extension-less folders.
  • sort sorts all extensions alphabetically (somehow uniq doesn't work without it).
  • uniq compiles the duplicate counts.
Alternatively,

find . | sed -e 's/\.[^.]*\.\(.*\)/\1/g;/\//d' | sort | uniq -c > ~/files3.txt
  • sed performs grep's deletion of extension-less folders by detecting remaining slashes in the filename (assuming folder pathnames don't contain dots).

    Wednesday, February 8, 2012

    Quick web crawling

    wget -r -l 1 --http-user=$USER --http-passwd=$PASSWD $URL

    will get you a level-1 depth crawl of all links starting at $URL. $USER and $PASSWD are optional, of course, in case the page requires HTML authentication.

    Now that is nice!

    Empty line removal

    A simple sub-task in sed, handy to keep around in case one does not know sed well:

    sed '/^$/d' myFile

    That's it! So I learned how to do deletions today :)

    Thursday, February 2, 2012

    Column concatenation

    When processing text files on a shell, sometimes you want to concatenate columns from different files. Maybe you have the students' names on one file and their grades on the other, or something. Anyway, I found several ways to concatenate columns, and due to their potential time-saving capability, I'm posting them up here:

    • Method 1: pr (print)
    • Method 2: paste
    • Method 3: awk
    The first two will allow you to simply concatenate columns horizontally, and nothing else. Most useful perhaps for numbering rows in a text file (aided by seq), or concatenating two perfectly aligned files. I've had both needs at times.

    The third method extends upon the first two, and allows you to shuffle the columns onto another order, or to join columns based on their values. The first use case is neatly exemplified here:


    > cat file1
    one two three
    one two three
    one two three
    one two three
    
    > cat file2
    four five six
    four five six
    four five six
    four five six
    
    > pr -m -t -s\  file1 file2 | gawk '{print $4,$5,$6,$1}'
    four five six one
    four five six one
    four five six one
    four five six one

    See how it uses pr to concatenate the columns first, and THEN uses awk to shuffle them. I went through the manual pages, and it seems pr is geared towards formatting text for page printing, while paste is a more simple operator. I haven't used them much, but I'd suggest paste over pr in general. Both both have their uses.

    Then this other webpage suggests the following command, which I have not tried:

    awk '
      # store the first file, indexed by col2
      NR==FNR {f1[$2] = $0; next}
      # output only if file1 contains file2's col2
      ($2 in f1) {print f1[$2], $0}
    ' file1 file2

    It seems complicated and I don't yet quite understand it, but if it does what it claims, it should come very much in handy.

    And a supporter of the join command suggests a slightly cleaner method:


    You can do that with a combination of the sort and join commands. The straightforward approach is
    join -j2 <(sort -k2 file1) <(sort -k2 file2)
    
    but that displays slightly differently than you're looking for. It just shows the common join field and then the remaining fields from each file
    "1431_at" "3973" 2.52832098784342 "653" 2.14595534191867
    "207201_s_at" "1826" 2.41685345240968 "1109" 2.13777517447307
    
    If you need the format exactly as you showed, then you would need to tell join to output in that manner
    join -o 1.1,1.2,1.3,2.1,2.2,2.3 -j2 <(sort -k2 file1) <(sort -k2 file2)
    
    where -o accepts a list of FILENUM.FIELDNUM specifiers.
    Note that the <() syntax I'm using isn't POSIX sh, so you should sort to a temporary file if you need POSIX sh syntax.

    I also haven't sat today to understand it, but it looks promising.
    I should be trying them out soon. Hope you do too.