Useful command-line scripts for web developers (or anyone else really)
blog.emson.co.uk
blog.emson.co.uk
This is a script written by a colleague. http://www.visualcortex.co.uk/. Add the following function to your .bash_profile in Apple OSX. Now open a directory in Finder, then open terminal and type cdf, your terminal will now change directory to the same one as the last Finder opened.
# function to change directory to the one set in the last opened finder.
cdf () {
currFolderPath=$( /usr/bin/osascript <<" EOT"
tell application "Finder"
try
set currFolder to (folder of the front window as alias)
on error
set currFolder to (path to desktop folder as alias)
end try
POSIX path of currFolder
end tell
EOT
)
echo "cd to \"$currFolderPath\""
cd "$currFolderPath"
}http://www.macupdate.com/info.php/id/23173
It gives you an icon in Finder that changes the directory in your terminal to the one in the Finder window. There are some options, like have it open a new terminal, or change the folder using pushd, so you can popd once your done and return to the folder it originally was in.
I like the script you provided, though, as it saves me from having to use the mouse (no button click) and I can easily select which terminal to do it in. Note that I had to remove the quotes around the first EOT to get it to work.
While there are certainly some people who will pick apart examples like these and learn new tricks, I've seen enough copy-and-paste programming to know that many won't.
$ ls | grep -e .*5.*
Would be better as: $ find . -name '*5*'
or if you insist on using a regex: $ find . -regex '.*5.*' $ ls *5*
??The find command is more powerful (descending into subdirs, etc.), but the original example in the link only specified the current directory.
$ ls -d *5*
Otherwise you get a listing of any directory with a 5 in the name. ls *5*
will fail because the argument list was too big for execve(2). Would I design it that way? No, but people do (sometimes without really thinking about it), and you still have to get work done.New users should be taught find(1) because it always works.
However, in the example in the article, he was using "ls" piped to "grep" in order to find all files with a 5 in the name. That would suffer from the same consequences you mentioned, on such systems, and is inefficient and verbose.
Note, I agree with your advice to teach "find" (and "xargs") to users.
ls | grep 5
is reliable where ls *5*
is not. (Well, except for awful names that require "find -print0", or preferably having the file taken out and shot along with its creator.)I'm actually not a fan of xargs. It's more unixy, but somehow I find its options hard to remember. Off the top of my head I find it easier to do
find -exec blah {} +a silly usecase would be reversing all the file names:
ruby -e '`ls -1`.each_line { |x| `mv #{x.chomp} #{x.chomp.reverse}` }'
pbcopy is pretty cool feature though.
Also you may want to look at commandlinefu.com: http://www.commandlinefu.com/commands/tagged/34/bash
Why?
Things like that make porting from Linux to BSD and other Unices tons of fun.
for i in *X*; do mv $i ${i/X/Y}; done $ rename s/foo$/bar/ *foomplayer `clive -e http://www.youtube.com/watch?v=SZRyry_B7TY | awk -F'","' '{print $2}'`
You would need 'clive' package.
Here is a one-line example, given two parameters. $1 is the archive name prefix and $2 is the directory to archive.
tar -cvzf ${1}-$(date +%Y%m%d-%H%M).tar.gz $2
Note, if $2 contains path information (such as absolute path), that path will be stored in the tar. So it is usually used with the working dir as the parent of $2. -A NUM, --after-context=NUM
Print NUM lines of trailing context after matching lines. Places a
line containing a group separator (--) between contiguous groups of
matches. With the -o or --only-matching option, this has no effect and
a warning is given.
-B NUM, --before-context=NUM
Print NUM lines of leading context before matching lines. Places a
line containing a group separator (--) between contiguous groups of
matches. With the -o or --only-matching option, this has no effect and
a warning is given.
-C NUM, -NUM, --context=NUM
Print NUM lines of output context. Places a line containing a group
separator (--) between contiguous groups of matches. With the -o or
--only-matching option, this has no effect and a warning is given. find $1 -name $2 | xargs egrep -nC3 $3 | less
So, say: find ./ -name "*.rb" | xargs egrep -nC3 'gsub' | less
You'll get the matching line, three lines before and three lines after, as well as file name and line numbers. #!/bin/sh
cd /proc
ps auxw | grep apache2 | grep 'Rl' | sed -e 's/ \+/ /g' | \
cut -d' ' -f2 | egrep '[0-9]+' | xargs ls -l | grep cwd
Basically this will print a line for every instance of every apache virtual host that is 'running' right now.It's Linux specific.
CommandLineFu is a much more generalized command-line collection, has a few clever ones. Not just web developers, but anyone who uses *nix in general. Specially the top rated ones
tail -1000 access.log | cut -d' ' -f1 | sort | uniq -c | sort -rn | head
A quote:
"ack is a tool like grep, aimed at programmers with large trees of heterogeneous source code.
ack is written purely in Perl, and takes advantage of the power of Perl's regular expressions."