Showing posts with label csh. Show all posts
Showing posts with label csh. Show all posts

Thursday, May 29, 2008

Simple Shell One-Liner To Enumerate File Types In Linux and Unix

Hey there,

Lately, we've been focusing a lot on Perl "one liners," from mass file time syncing to name and IP resolution and I thought it was only fair that we should write a post about a shell "one liner" for once. After all, most standard Unix and Linux shells are perfect for that purpose :)

Here's a very quick way to take an inventory of all the different file types (including directories, sockets, named pipes, etc) that exist in a given directory tree and provide a tally of each file type. I'm not entirely sure that I care if I have 15 ASCII text files and 2 Perl scripts in my current working directory, but this little piece of code must be able to help someone somewhere accomplish something, even if it is only to use as a smaller part of a larger organism ;)

This works in pretty much any standard shell on every flavour of Linux and/or Unix I've tested (ash, sh, bash, jsh, ksh, zsh, even csh and tcsh, which is huge for me since I never use those shells. One day, soon, I will redouble my efforts and just learn how to use them well, which, hopefully, won't result in my writing a whole bunch of posts about "cool" stuff that everyone has known about for the past few decades ;).

This one-liner could actually be written as a script, to make it more readable, like this:

#!/bin/sh
find . -print | xargs -I var file "var"|
awk '{
$1="";
x[$0]++;
}
END {
for (y in x) printf("%d\t%s\n", x[y], y);
}' | sort -nr


But, since I'm a big fan of brevity (which is about as far away from obvious as possible if you consider my writing style ;), I would run it like this:

host # find . -print|xargs file|awk '{$1="";x[$0]++;}END{for(y in x)printf("%d\t%s\n",x[y],y);}'|sort -nr

In my terminal, that all comes out on one line :) And here's the sort of output you can expect:

host # find . -print|xargs file|awk '{$1="";x[$0]++;}END{for(y in x)printf("%d\t%s\n",x[y],y);}'|sort -nr
23 Bourne-Again shell script text
11 ASCII text
10 perl script text
5 pkg Datastream (SVR4)
4 directory
4 ASCII English text
2 UTF-8 Unicode English text, with overstriking
2 Bourne shell script text
1 RPM v3 bin i386 m4-1.4.10-1


and, just to confirm the file count, we'll change the command slightly (to total up everything, instead of being particular -- another "one-liner" that's, admittedly, completely unnecessary unless you're obsessive/compulsive like me ;) and compare that with a straight-up find:

host # find . -print|xargs file|awk 'BEGIN{x=0}{x++}END{print x}'
62
host # find .|wc -l
62


Good news; everything appears to be in order! Hope this helps you out in some way, shape or form :)

Cheers,

, Mike

Thursday, April 3, 2008

Setting Static And Dynamic Window Titles From The Shell

Hey There,

Following in the tradition of our "terminal beautification" posts on using color in the shell and making fancy looking menus with tput, today we're going to take a look at setting the title of your terminal window from within the shell.

This is actually a slight variation from what we've looked at before, but it can be just as helpful, since you'll be using your shell to modify the "content" of your terminal's title in Windows (or whatever OS you use). This can be a great help in keeping organized. Most terminal clients provide functionality like this as a standard, but don't allow you to modify the defaults (like every window will have the title of the host you're connected to, etc) without jumping through hoops on the Windows (or Mac) end of things.

The simplest thing to do is to set static window titles in "xterm." In fact, if you're running X-Windows, you don't even have to do anything fancy, since most widely-distributed versions of it contain command line arguments specifically for doing this. For instance, the following command line (invoking xterm) would bring it up with the title "This XTerm Is Mine" (and, for goofs since it's an available option, an icon titled "This Icon Is Mine, Too!"):

host # xterm -T "This XTerm Is Mine" -n "his Icon Is Mine, Too!" &

Simple enough. It's also fairly simple to set static window titles for almost any terminal emulator (like PuTTY or SecureCRT) by typing at the command prompt or including a line in your .profile, .bashrc or .zshrc (Or whatever initialization file you use if you use an alternate shell).

Here again, we come back to some concepts that we first went over when we looked at using color in the terminal. Your window title is created by using very similar "echo -e" syntax (include the initial "escape") and can be done at the command line by typing the following:

host # echo -e "\033]0;This Is My Window Title And My Icon Title\007" <--- This pretty much works all the time
host # echo -e "\033]1;This Is Just My Icon Title\007" <--- This works sometimes depending on your terminal
host # echo -e "\033]2;This Is Just My Window Title\007" <--- This pretty much works all the time

In the above three lines, we set the window and icon title, icon title and window title, respectively. Some of these statements may not work on your terminal, so you'll have to test, but (in my experience so far) at least one of them should. Usually the first one (setting both the icon and title) is your best bet.

Now, if we want to have our window and icon title change dynamically (we're going to forget about the icon-only and window-only settings, since they can be derived by just substituting the "0" in the following lines with either "1" or "2," per the examples above) all we have to do is integrate the escape sequences into our command prompt. In some shells this functionality has been accounted for. In others, we can force it.

1. Bash - To set this in bash, we'll just set the value of the PROMPT_COMMAND variable, either at the command prompt or in our .bashrc (or .profile) for permanence:

host # PROMPT_COMMAND='echo -ne "\033]0;${HOSTNAME}:${PWD} # \007"';export PROMPT_COMMAND

and, you'll notice that your window and icon titles are now something like:

host1:/users/user1 #


and that the window and icon titles will change whenever you change directories :) We'll do the same command line string for the other shells, so this post maintains some consistency.

2. Zsh - To set this in zsh, all we need to do is set the value of the precmd function at the command prompt or in our .zshrc, like so:

host # precmd () {print -Pn "\e]0;%n:%~\a"}

3. Ksh - To set this in ksh, all we need to do to get the same result is type the following at the command line, or include it in our .profile (Admittedly, this can be a little tricky since you have to insert the actual control characters into the prompt - For more info on how to do that, check out our previous post on how to really represent control characters within files). Note, also, that setting PS1 will change your main command prompt, so, after the ctl-G, I've added "${PWD}# '" which will be our actual command prompt, as opposed to our new window title. You should replace this with whatever your command prompt already is if you want to keep it the same:

host # PS1='^[]0;${USER}@${HOST}: ${PWD}^G${PWD}# '

And you can use that for most other shells, except...

4. Csh/Tcsh - To set this in csh/tcsh, you can use the "settitle" alias (Again, you'll need to manually put in the real control characters and the title is slightly different since my tcsh/csh knowledge is fair-to-middlin' in this respect ;)

host # alias settitle 'set t=$cwd:h;echo -n "^[]2;${HOST}: "!*"^G"'

And that should be all there is to getting yourself all set up to have dynamic and/or static window and icon titles for whenever you want or need. Here's hoping you can find a window and icon naming scheme you can live with and enjoy :)

Best wishes,

, Mike