I’m a fanatic about fixing warnings and errors in my code. Whenever I see one I tend to fix it right away which helps make it easy to see new ones when they pop up. However, there are occasions when you just can’t fix them. For instance, you might be using an open source bit of code without the time, knowledge, or commit access to fix a warning. In such cases a lot of warnings in a foreign piece of code can make your own hard to find due to the deluge of yellow icons all over the place. Well, fear not. There is a way to turn off warnings on a per file basis in Xcode.
Turning off warnings on a per file basis is super simple. All that is required is a compiler flag. Here’s the step by step process.
- Open the Project Navigator in Xcode
- Click on the Project icon at the very top of the navigator
- In the resulting detail pane select the target that you are working with
- Select “Build Phases”
- Expand “Compile Sources”
- In the list locate the file that you’re interested in
- Double click the column under the “Compiler Flags” column next to your file
- Add a -w to the resulting dialog
- Click “Done”
- Build your now warnings free project
Compiler Flags are extremely useful in certain situations. Not least among these is turning off ARC on a per file basis. To do so for a file simply add the -fno-objc-arc compiler flag.
Do note that suppressing warnings in your code base should be used judiciously. Be sure that you have a very good reason for doing so. With great power comes great responsibility.
Developing software in a solo environment has its pros and cons. On the upside you have complete reign over the code base (no problems with ownership here), freedom to follow specific designs and an ability to express your creativity. On the other hand, the very nature of the activity can be your down fall; tunnel vision and shortsightedness can eclipse all of your efforts.
There is a way out of this quandary and its called peer review. The mere mention of “peer review” can strike fear and foreboding into the hearts of developers. But, like it or not, this egoless programming practice has the power to deliver.
Outside input can lead to an increase in production quality and ultimately product appeal. Here’s a few ways to get outside input and ideas if you’re flying solo:
- Direct communication with friends. Friends that you’ve made through previous jobs, ventures, or virtual contacts made real are great sources of input. When in the same industry they can provide a unique perspective. If it has been a longtime since you’ve touched base then invite them out for lunch, or better yet a beer, in order to reconnect.
- End Users. The end users of your product are an extremely valuable source of feedback. While a user may not be privy to the nitty gritty code details they will have an opinion about what is good or bad about your interface. Running a public or private beta will give you the chance to gather valuable feedback and roll it into a product before going live with it. For iPhone development take a look at TestFlight which is an awesome service for distributing beta builds and getting feedback from your test team.
- User groups. There is a good chance that there is a Cocoa developer group that meets regularly in your area. A few places to start would be CocoaHeads, NSCoder Night, and if you’re in Austin CocoaCoder. Getting out and mingling with other developers is a great way to cultivate ideas, get feedback and make a few friends. Try giving a short presentation to the group on some code or a technique that you’ve been working on. Not only will this give the group a chance to discuss a topic but it can help you validate ideas or to open up new avenues of thought.
- Virtual community. Participation in online forums, email lists, IRC channels, and of course blogs can be another source of outside input. While readily available the quality of this sort of feedback can tend towards the inflammatory. Be sure to research your questions and always interact per the guidelines of your chosen group. Oh, and be sure to don your flame retardant suit before dipping your toes in.
Whatever avenue you pursue to gain outside input it has the ability to not only improve on your own designs but to also increase your creativity. New ideas yield more new ideas and so on. So, if you’re feeling like you’ve hit a brick wall or that you need a second opinion try getting some outside input.
There used to be a senior exec in a company that I worked for who liked to say, “Feedback is the breakfast of champions”. Visuals from a literal translation of that Ken Blanchard quote aside, it has the power to transform anything. Feedback, in all of its forms, is often a tough serving to consume but a good helping of the right sort can push you beyond current limits and plateaus.
The Good,
When I think of that quote I imagine what kind of feedback the exec was talking about. For me it meant feedback from peers and end users. Depending on the crowd that you hang out with it can actually be quite difficult to get good constructive criticism. I know, I know, what you’re thinking. This guy is asking for it? Yea, as long as it contains that operative word constructive and is meant with sincerity. Feedback is often the only way for you to see beyond your own narrow view of the world. Think of the Truman Show. Here you have this guy who has known nothing else but a little island for his entire life. Then little by little he starts to notice inconsistencies which make him think about the world around him. Had those quirks never happened or had he failed to notice them he would still be sitting there on his TV show. Feedback is the express train to realization.
Constructive criticism coming from your peers can take you to new levels of your craft. Of course, it’s up to you to decide if any one piece of feedback takes you in the direction you want to go as a developer, individual, astronaut, or whatever. This requires some introspection on your part. Developing a bit of a rhinoceros skin and a good humor about yourself also helps to digest the horse pill that can be peer feedback. However, the best peer feedback is often of the positive persuasion. A simple, “Good job” or “Man, that’s great” can do wonders to spur someone on in their current direction.
Assuming that you’re a software developer/publisher, you can have feedback from end users. Feedback of this sort can put greenbacks in your pocket book. When a user emails to notify you that there is a UI bug or that they don’t understand the usage of some feature it is your clue that something may be up. The same or similar item coming from two, three, or even more people should start to perk up your spider senses to a potential improvement in a design or work flow. Again, introspection is the order of the day when deciding if a request or issue falls along the direction and intent of your particular flavor of software.
the Bad,
Being the bearer of feedback can be just as tough as receiving it. That is, if your intent is to be constructive (and I hope that it is). Simply blurting out your observation of flaws comes across as strictly criticism and that’s bad. Instead, hold back the thought for a bit and think of ways to improve on the subject at hand. I mean, you see a flaw so you must have an idea of how things could be better. Right? Reverse roles with the person and think about how you would want to hear the news that you are about to deliver. Finally, provide your critique along with a suggestion on how to improve. Running through this sequence becomes second nature once practiced for a while. Some people will do it naturally and don’t even think about it. Others need a process to follow. Some characteristics of good feedback include:
- Transfer of information rather than the giving of advise
- Covers a specific issue rather than a general one
- Focuses on the content rather than the person
- Offered with empathy
Just as bad as not being able to take feedback is never giving it. Floating merrily along accepting the status quo lies in a direct line towards failure. Yours or someone else’s. It could take years or even decades to materialize but sooner or later such a static nature will break down. Often an unwillingness to provide feedback is really masking a desire to avoid receiving it. If that’s you then start small. Give yourself time to develop the skills of giving and receiving feedback. I think you’ll be better for it in the long run.
and the Ugly
Trolls and flame warriors need not apply. We all know the type of inflammatory feedback that a supposedly anonymous internet can elicit. There is something about the feeling of anonymity that can draw out some of the more basal aspects of human nature. In short, there is little you can do but surround yourself with as many upstanding people as possible and simply ignore the occasional flame. Responding to outright deleterious comments or feedback usually only fans the flames and invites more of the same. Use that rhinoceros skin and good humor to the best of your ability and ignore it.
That’s a wrap
There you have it. The good, the bad, and the ugly of feedback. Sometimes it takes stepping outside of yourself in order to see the larger picture but feedback is a great way to grow an idea, a product, or yourself.
Feedback. It’s not just for breakfast anymore.
Note: This is a repost from my personal blog at http://shanecrawford.org
Did you make a small improvement in some area of your apps today? Your design? Your business? Practice Kaizen and you would have. Kaizen is a Japanese philosophy for continuous improvement which has been applied to fields as varied as manufacturing and game development. While the philosophy includes making changes and adjusting based on their outcome one of the more useful aspects is improvement by continually making small changes.
Toyota famously uses this technique to increase manufacturing efficiency and productivity. Every worker is empowered to stop their production line suggest an improvement and work it into their larger process. They have formalized the process and made it a part of their corporate culture. Small changes made continually have led to a power house of manufacturing.
I think that Apple also uses a form of Kaizen. We all know that Apple makes incredible products and is known for innovation. But, they are not always first to market. Nor are many of their products initially released with the ultimate feature set. They have an innate knack for launching a product with the right feature set and then rapidly and continually improving it over time. All informed by a philosophy of simplicity and elegance. In fact, they are relentless about improvement even to the point of radically changing established and accepted products. Remember the very first iPod? It was a clunky device by todays standards. It also wasn’t the first nor the best digital music player of its day. But, it soon became the dominating music player as a result of relentlessly improving the device.
It’s amazing how quickly a group of small changes can result in a large one. By continually making small improvements you can quickly outpace competitors, increase end user satisfaction and create a product that is established in its niche. This technique is especially powerful when used by small teams or solo developers who can move nimbly but lack the resources of a larger outfit. Be relentless in your small but continual improvements and others will wonder how you get so much done. One brick at a time, that’s how. Add the philosophy of Kaizen to your mindset and make at least a small improvement in your app or business each and every day. Down the road you’ll be glad you did.
There has been some discussion recently on Twitter regarding developing from multiple machines. I work this way and it can be liberating. While in the office I typically work from a Mac Pro with a 27″ display. Ah, screen real-estate. But, I like to be mobile so I also work from a 15″ Mac Book Pro. When I’m ready to head out of the office for a while the last thing that I want is to worry about setting up my dev environment. I just want to grab the laptop and sprint out the door. Likewise when I return I want everything ready to go on the desktop. Keeping development environments synced between the two can be a real pain. That is unless you make use of “the cloud”.
I can hear you asking, “Isn’t this what version control systems are for?”. Yes. I am a big fan of version control and have used numerous systems over the years. Currently I use Git. I love the fact that I don’t need to be connected in order to work against the repo like I do with Subversion or Perforce. In addition, I think that the self contained nature of Git lends itself to this type of setup. I’m not so sure that a system like Perforce would fair so well. In a team environment version control is a no questions asked must have. In fact you should always use version control, even if you work solo like I do.
However, in order to keep everything in sync between machines I use Dropbox. Everything goes into the Dropbox folder. Source code, assets, Git repos, project files. The whole enchilada. Everything except for build directories which are regenerated with a simple build. The size of your project, especially assets, can be an issue when syncing over a slow network so keep that in mind. Fortunately, if both machines are on the same network then Dropbox will detect it and use the LAN Sync feature which will sync files over your local network vs the cloud. Unless you don’t have much code or you have managed to max out your referrals with Dropbox you’ll probably need to spring for one of the paid plans. Typically I like to keep all of my projects under a single top level directory. But, I like to keep that directory in my user space. As such I had a major aversion to moving everything over to the Dropbox folder. A simple symlink from the Dropbox folder to my preferred space solved that issue.
I’ve run into two caveats with this rather simplistic setup. First is not to have the same project open under Xcode at the same time on different machines. Otherwise strange and potentially harmful behaviors can and do occur. This means that when I leave the house I need to be sure that Xcode on the desktop is shutdown and vice versa. A small but important point. Second, remember that everything is synced immediately all of the time. So, if I’m working on a large Photoshop file, for example, from a coffee shop with a slow connection this could be an issue (especially with a severe -S habit). In such a case I might temporarily turn off Dropbox syncing until I can get to a faster network or back to HQ. Not ideal but I’m usually working on source files which sync quickly. If you desire more control over what is synced and when then this Stackoverflow post outlines a way to use Dropbox as a Git bare repo rather than just going all in on the syncing fire hose. Additionally, you may want to disable Growl notifications for Dropbox since they can get annoying after a while. There have also been some recent security concerns with Dropbox. I suppose that your level of trust in them and your comfort level with others potentially seeing your code will dictate whether or not you use a setup like this. For me the benefits outweigh the downside.
Even with a great automatic code syncing environment in the cloud you shouldn’t rely on it as your sole source of backup. Keep using your version control systems hopefully hosting offsite somewhere. I also use the great online backup utility Arq to regularly backup my important files including my development environment. In addition, I periodically create a sparse image of my entire hard drive using SuperDuper. That’s at least four copies of my code three of which are offsite. There is also a copy on my alternate machine ready to go. I sleep pretty well at night.
Xcode 4 has brought major changes but one of my favorites are the built in code snippets (maybe I’ll share mine sometime). However, there is no built in way to sync them between machines which can be frustrating and a major hassle when using a setup like this one. If you run into this then xcodesnippets is for you. It’s a simple ruby gem which packages up and organizes your snippets for easy transport to other machines. Unfortunately, there is no online syncing built in so you need to copy the snippet bundles over manually but otherwise it works great. It does seem however that using the magic of symlinks and Dropbox you might be able to setup some auto syncing of snippets even without such a tool. If you try this then please let us know how it works out.
I love the ability to run out the door with my laptop in hand without having to worry about having everything ready to go. It is. Likewise when I’m in the office I love being able to fire up Xcode on the Mac Pro and get to work immediately. As developers we spend all day in our environment and as such it is a very personal thing. So, this type of a setup may or may not work for you. Whichever the case please share your experiences and what works in your world.
Happy coding.
Occasionally I run across some video out on the web which peaks an interest that seems to draw a line back towards my indie development efforts. They may be directly related to some technical topic or more often than not totally off the beaten path. I’m going to link to a few of them here in the hopes that they spark something in you. May they help to provide a guiding light down the path to Indiedom.
First, Bruce F’n Lee!! Bruce comes off as very inward focused and zen-like. Inspiration for being flexible as an indie developer. Be water my friend.
All of us have Genius. Don’t be afraid to find and expose yours. Sometimes its hard to let your creation show for fear of “feedback”. Push on through and let your creativity shine.
Avoid the inevitable doldrums that follow the high you feel after coming up with a new idea. Stop dreaming and start doing.
Classic guerrilla marketing techniques from the godfather of the delicious generation.
Very cool and inspirational animated talk about the underpinnings behind what motivates us. Good to keep in mind when you find yourself lacking motivation.
Just a few videos that I’ve found inspirational and I hope you like them too. This is my last blog post for iDevBlogADay for a while. I’ll be falling back to the end of the rotation and the next dev with great stuff to write will be filling this slot the next time around. However, I hope that you subscribe to the RSS feed and hang around since I’ll still be posting about an awesome new project that I’m just starting.
This post is a part of the iDevBlogADay group of Indie development blogs. Thanks to @mysterycoconut for managing such a great site.
A few days ago we returned from a week long working vacation down to the coast. This wasn’t a visit to a client site or a trip to an extension office. It was more of a re-location of current activities. A Busman’s Holiday. Our days were filled with long walks on the beach, trying out the local restaurants and working on special projects. That’s right, working, on vacation.
Being an Indie developer means that you can be somewhat of a Bedouin1 traveling about the countryside laptop in hand. A fast internet connection, a power outlet, and my laptop are all that I really require to be productive. Well, almost. A supportive spouse who has a similar mindset is critical. For the third year in a row now we’ve made this trip down to a sleepy fishing town on the coast and each year great things come from it.
There’s one rule to a Busman’s Holiday. Don’t work exclusively on existing projects. Pick something new that you’ve been wanting to explore or start something that you’ve been wanting to get to. Working on a fun special project multiplies the creative effects of your work and can take you to truly undiscovered territory. In fact, my primary product, Mathemagics, started out this way on a trip a couple of years ago. Last year saw the brainstorm and start of another successful project. And this recent trip was no different in setting the tone for the rest of my year as an Indie.
Have you ever woken up in the middle of the night with the solution to a problem as if your mind was working while you were asleep? Or had a great idea while in the shower? I think this happens because in those situations our minds are closer to a state of relaxation. Stress of day-to-day activities fades away and opens the pathways our brains need to make the leaps of thought that manifest themselves as creativity. A Busman’s Holiday is like that. Removed from your daily work environment and nestled in a relaxing setting the ideas begin to flow and hyper productivity sets in.
So, if you have the means then you might want to take a Busman’s Holiday. Pick a relaxing spot somewhere near where you live, set the expectations for the family that this is just work but somewhere else and go for it. Step outside of your normal daily activities and temporarily relocate to your creative zone.
1. If you are in or near Austin Texas then you can get a weekly dose of nomadic life by attending Cafe Bedouins on Tuesdays.
This post is a part of the iDevBlogADay group of Indie development blogs. Thanks to @mysterycoconut for managing such a great site.
This, part deux, continues part 1 of Command Line Fu.
Do This Over There
Spinning up and running a server somewhere on the internet is extremely easy these days. From Amazon EC2 to Slicehost having a remote machine running 24/7 is well within the reach of most devs. It also makes system administrators out of us. The powerful ssh command can help tame your network of servers so that you can spend a little extra time with friends and family. Most people think of ssh as a secure telnet (remember telnet?) but it’s oh so much more than that.
One of my favorite uses of ssh is in remotely executing commands. Here’s what one looks like:
$>ssh username@myserver.com 'apachectl -k restart'
That’s it. Simply put your command in quotes at the end of the ssh command line. The command is executed from your local machine but runs on the destination server. String 10 of those together in a script and you can restart your entire web server farm from your local machine by executing a single script. The ease and automatic nature of this hinges on setting up ssh for auto login.
You can take it to the next level by combining scp with ssh remote command execution. Consider having a stable of scripts that help you manage your servers all kept centrally on your local machine. When the need arises scp one of them over to the target machine and then use ssh to remotely execute it. Keeping all of those scripts locally reduces admin headaches by having copies distributed all over the place.
As an added bonus you can use ssh to securely tunnel out of wherever you happen to be. For example, you find yourself sitting in a strange coffee shop wanting to check your email without having to worry (note pop3 sends your email password in plaintext every single time it checks for new mail). You can easily divert your email over a secure connection so that anyone that happens to be monitoring network traffic doesn’t see your secrets.
$>ssh -f username@myserver.com -L 2000:mailhost.com:110 -N
The -f argument backgrounds ssh, username@myserver.com is your username at your servers hostname, -N tells ssh to not try executing this as a command on the remote machine. The -L argument is where the magic happens. In the args to -L 2000 is the port on your local machine, mailhost.com is your mail servers host name, and 110 is the port on the remote mail server machine. Now simply switch your email client to connect to localhost on port 2000 as your mail server. Now all of your email traffic for that account is secure from the point of your localhost to your server (your server forwards the request out to the real server from there). This technique works with just about any ports that you want to tunnel using your server as a middle man.
Interactive History
After working at the command line for any length of time you invariably need to re-execute some command again. You can either re-type it, often tedious, scroll through previous commands, takes forever, or you can search for it and just hit enter. Searching the command history is easy. Just hit CTRL-R at the prompt and start typing any part of the command. Search results will pop up:
(reverse-i-search)`sq': sqlite3 db/data.sqlite3
From this point you can hit Enter to execute the command or Right Arrow to put the command at the prompt so that you can edit it. If you have many similar results then you can continue hitting CTRL-R once you have a result to cycle through all matches.
Bashing History
Searching with interactive command history is handy. But, we can take it to a whole other level. Bash allows you to refer to previous commands and arguments withing those commands via a simple shorthand. Once you grok the shorthand you’ll be zipping through previous commands.
$>apt-get install git
Permission denied
$> sudo !!
sudo apt-get install git
Reading package lists... Done
The “!!” refers to the previous command in the history. So, executing “sudo !!” puts sudo in front that previous command. How many times have you executed a command only to re-execute it as sudo? Now it’s easy to do, eh? Here are some more variations to refer to previous commands:
!-2Â Â Â Â Â Â Â Â Â Â Â # Refer to the command 2 back in the history (!-3, !-4, etc)
!find         # Previous command that starts with 'find'
!?find?      # Previous command that contains 'find'
!! -la       # Previous command adding -la as an argument
!!:1Â Â Â Â Â Â Â Â Â Â # Refers to the first argument of the last command
!!:3-5 Â Â Â Â # Refers to arguments 3, 4, and 5 of the previous command
!!:0 Â Â Â Â Â # Refers to the command (no arguments)
!!:-2Â Â Â Â Â Â Â Â # Refers to the command and the first two arguments
As you can see there is a lot of power there in referring to the previous command and arguments. Say, for example, you’re creating a tar file and realize that you have added an unwanted file (file2).
$> tar -xvf backup.tar file1 file2 file3 file4 file5
-- Ooops. Didn't want 'file2' in the list --
$>!!:-3 !!:5-7
tar -cvf backup.tar file1 file3 file4 file5
a file1
a file3
a file4
a file5
By using a simple shorthand the previous command was quickly executed sans the undesired argument. With a little practice this speedy but somewhat cryptic command structure becomes second nature.
So there you have it. My list of Master Command Line Fu tricks. Study them. Practice them. Before you know it you’ll pick that rabbit out of the hat while everybody sits out there wondering how the hell you did it.1
1. Gordon Gekko: “The richest one percent of this country owns half our country’s wealth, five trillion dollars. One third of that comes from hard work, two thirds comes from inheritance, interest on interest accumulating to widows and idiot sons and what I do, stock and real estate speculation. It’s bullshit. You got ninety percent of the American public out there with little or no net worth. I create nothing. I own. We make the rules, pal. The news, war, peace, famine, upheaval, the price per paper clip. We pick that rabbit out of the hat while everybody sits out there wondering how the hell we did it. Now you’re not naive enough to think we’re living in a democracy, are you buddy? It’s the free market. And you’re a part of it. You’ve got that killer instinct. Stick around pal, I’ve still got a lot to teach you. ”
This post is a part of the iDevBlogADay group of Indie development blogs. Thanks to @mysterycoconut for managing such a great site.
Almost every developer needs to get out to the command line once in a while. Some of us almost live there. So, here are a few tips and tricks that I’ve picked up over the years. May they help speed you along to your final command line destination.
Find Exec
Have you ever wanted to execute a command against every file in a directory? Or every file that matched a search? Well then, find with exec is your friend. For example, say we wanted to change the permissions on every file within a directory.
$>find . -type f -exec chmod 744 {} \;
The first argument, the ‘.’, tells find to start the search from the current directory. The ‘-type f’ says to look for only files. The -exec option tells find to execute the following command against every search result. Each result is substituted in the place specified by the {}. The ‘\;’ terminates the command. So, basically this command quickly executes a ‘chmod 744’ against every file found in the current directory. You could also add a ‘-name *.sh’ in order to further limit the search to all files ending in a ‘.sh’.
$>find . -type f -ls
This version of the command (the one with the -ls) simply shows you what files will be operated on as a result of the find. It is good practice to run this command first using all the same options except replacing the -exec with the -ls. The -exec option can be particularly destructive so know what what files you are operating on. Performing a ‘rm -rf’ as a result of a find against the root filesystem will send your day in the wrong direction. So, use the -ls version of the command first to see what files will be used.
Right Sed Fred
“Who’s sed? Sed’s dead baby. Sed’s dead.”1 Forgotten maybe but not dead. Sed stands for “stream editor” and it’s one of those old school neckbeard command line utilities that should be in your arsenal. Sed is prefect for picking through large amounts of text and twisting it to your will. Take this over simplified csv file as an example:
$>cat numbers.csv
one,two,three
four,five,six
seven,eight,nine
With sed you can do crazy cool stuff like the following:
# Delete lines
$>cat numbers.csv | sed -e '2d'
one,two,three
seven,eight,nine
# Print or add lines (prints current line)
$>cat numbers.csv | sed -e '1,2p'
one,two,three
one,two,three
four,five,six
four,five,six
seven,eight,nine
# Substitute text
$>cat numbers.csv | sed -e 's/one/zero/g' | sed -e 's/,/:/g'
zero:two:three
four:five:six
seven:eight:nine
The -e on the sed command line tells it to accept what follows as the command. You can also write entire files of sed commands but I never do this. Instead I tend to chain successive commands together using the unix pipe in order to get what I’m after (see the Substitute text example).
The sed command takes the following structure: [address[,address]]function[arguments]. Where [address] can be a line number or a regex style pattern. Here’s a few more examples that use variations of addresses:
# Add the following text after lines where the pattern is found
$>cat numbers.csv | sed -e '/one/a\
$>token'
one,two,three
token
four,five,six
seven,eight,nine
# Insert the following text before lines where the pattern is found
$>cat numbers.csv | sed -e '/four/i\
$>token'
one,two,three
token
four,five,six
seven,eight,nine
# Read in the file abc.csv and add it after lines where the pattern is found
$>cat numbers.csv | sed -e '/four/r abc.csv'
one,two,three
four,five,six
a,b,c
d,e,f
g,h,i
seven,eight,nine
# Delete lines 2 through 4
$>cat numbers.csv | sed -e '/four/r abc.csv' | sed -e '2,4d'
one,two,three
g,h,i
seven,eight,nine
# Delete the lines found between the two patterns
$>cat numbers.csv | sed -e '/four/r abc.csv' | sed -e '/four/,/e.f/d'
one,two,three
g,h,i
seven,eight,nine
And that’s just the beginning of the power of sed. Getting comfortable with the basic commands and structure of sed can allow you to whip out some minor change or pick through some complicated text in a flash. It’s a quick and powerful tool sitting there on your command line just waiting to be utilized. Man up the man pages (man sed) and check out some of the other cool stuff sed can do.
Before we leave sed here are some powerful sed one liners:
sed -e '$=' # Count lines (similar to wc -l) sed -e 'G' # Double space a file sed -e 'n;d' # undo double spacing sed 's/^M$//' # convert DOS newlines to Unix format. # (Press CTRL-V then CTRL-M to get ^M) sed = numbers.csv | sed 'N;s/\n/Â Â Â Â /' # Number the lines in the specified file sed -e 's/^[ \t]*//' # delete leading whitespace from each line sed -e 's/[ \t]*$//' # delete trailing whitespace from each line sed -e '/^$/d' # delete blank lines
Awkland
Awk is the pretty cousin to sed. When you have any semi-well formatted data with a known separator awk is your man (or gal). Awk’s power lies in printing various portions of columns of data. Strictly speaking they don’t need to be real columns of data but rather just have a known separating character. For example:
$>echo "one two three" | awk '{print $2}'
two
Awk’s default separator is conveniently the space. The ‘{print $2}’ is the awk command and tells it, in this case, to print the 2nd column of data as separated by a space. You can also change the separating character with the -F option:
$>echo "one,two,three" | awk -F, '{print $2}'
two
In this case the comma was specified as the separator. Whatever character immediately follows the -F will be used as the separator. Like sed, awk can make use of addresses to select which rows of text it operates on.
$>cat numbers.csv | awk -F, '/four/ {print $2}'
five
$>cat numbers.csv | awk -F, '/four/,/seven/ {print $2}'
five
eight
In the first example, the line with the word ‘four’ in it is selected and the second column is printed (‘five’). In the second example, the lines between the one that contains word ‘four’ and the line that contains the word ‘seven’ are selected and their respective second columns are printed (‘five’ and ‘eight’). You can also have awk read a file directly rather than using cat.
$>awk -F, '/four/ {print $2}' numbers.csv
five
However, I almost never do this since it limits my ability to chain commands together which is where the real power in sed and awk lie.
To round out awk here are some powerful awk one liners:
awk '{print $NF}'Â Â Â Â Â Â Â Â Â Â Â # Print the last field of each line awk 'NF > 3' # Print each line with more than 3 fields awk '{print $2, $1}' # Print the first two fields in opposite order awk '!/regex/' # Print only the lines which do not match the regex awk '/regex/{getline;print}' # Print the line immediately following the regex
Knock Out Blow
Sed and awk work together to land a powerful one, two knock out blow. Together they can chew through even the most thorny text munging problems. For example, I recently needed a script to determine the process id (pid) of a running process so that I could kill it. Easy with sed and awk at your side.
PID=`ps -aef | grep "unicorn master" | sed -e '/grep/d' | awk '{print $2}'`
What’s going on here? The ps command is listing all processes. This is piped into the grep command which picks out the one that I am looking for (the awesome unicorn ruby http server). The ps and grep together print out something like this:
root 19092 1 0 Feb10 ? 00:00:03 unicorn master -c /etc/unicorn/sites/test/unicorn.rb -E production -D
ubuntu 22562 7121 0 15:42 pts/0 00:00:00 grep --color=auto unicorn master
The pid I want is right there, 19092, but how do I get at it? Easy. Pipe the output into sed to delete the line picking up our running grep command (sed -e ‘/grep/d’) and then pipe that into awk to print out the second column of text, our process id.
$>ps -aef | grep "unicorn master" | sed -e '/grep/d' | awk '{print $2}'
19092
As you can see with sed and awk at your side crunching through nearly any text is possible. And it’s all done right there on the command line.
In the next installment I will move away from sed and awk to explore remote command execution, command looping, and some powerful kung fu master techniques to utilize your command history.
1. Zed is dead.
This post is a part of the iDevBlogADay group of Indie development blogs. Thanks to @mysterycoconut for managing such a great site.
The conventional wisdom says that a Lite version of your app draws in more sales to your paid app1. In my experience this has been true. Generally, the Lite version offers a limited experience with an option to upgrade to the full app at a certain point. The Lite version should offer just enough content or functionality to give the user an idea of what the app is like and still leave them wanting more. Getting this balance correct is crucial to the success of the Lite-to-Paid conversion. Other factors also come into play such as the verbiage used at the point of decision.
In order to determine the optimum text I decided to A/B test the text on the link used to launch the user over to the paid version of the app on the AppStore. The button is very visible right on the main screen of the app. Can’t miss it. When the app is first launched it randomly chooses one of four different variations of the text (I know, I know, I should probably call it an A/B/C/D test) and displays that version of the button text to the user. In order to keep things consistent the app tracks which version was selected and continues to show that version to the user from then on. The four variations that I chose were: “Buy, “Buy Now”, “More”, “Get More”.
For tracking purposes I added a signature to my LinkShare link which gets tracked whenever someone clicks on the link. LinkShare not only tracks the click throughs on these links but also purchases made in iTunes which originated from a click on one of them (maybe I will cover this in another blog post if there is enough interest). The system isn’t perfectly accurate since LinkShare tracks ALL sales associated with a link rather than just the sales to the app you linked to. Meaning that if someone clicked over to your app but decided to buy the $150 Beatles Box Set instead then that sale would be attributed to the link signature that was used. However, given a large enough sample space the non-app sales should even out and give a fairly good idea of the relative sales to your app from each version of the button text.
As it turns out I never really did anything with all of this. It’s been in the codebase for a year and a half. Ouch! But, what this does provide is a nice and large sample set to look at. Hopefully, I can put this info to good use at some point. Even better I hope that it is of a more immediate benefit to you.
In the table the ‘Member ID’ column is the custom signature that was set in the LinkShare link (one each for buy, buy now, etc). The clicks are the total number of click throughs (CTR) from the first of June of 2009 until Feb 4, 2011. The Sales column is the total amount of iTunes merchandise purchased as a result of a click on one of the links and Commissions are the LinkShare revenue generated on those sales.
The first thing that stands out are that the buttons with the text ‘More’ and ‘Get More’ generated more than twice the click throughs as the ‘Buy’ and ‘Buy Now’ links. Most likely this is due to the somewhat ambiguous nature of the the terms ‘More’ and ‘Get More’ (unintentional I assure you). I don’t really think the user knows quite what to expect when tapping buttons with those labels and purchasing the app is probably not what many expect. Or maybe it’s curiosity. What’s behind the ‘More’ button?
The ‘Buy’ and ‘Buy Now’ labeled buttons set expectations appropriately. When a user taps on one of them they pretty much know that they are going to a place where a purchase may take place (aka the AppStore). While the raw number of clicks is less than half that of the ‘more’ variety the sales associated with the ‘buy’ labeled buttons confirms this. For instance, for the ‘Buy’ button an average of 0.44 sales occurred per tap (1640/3768 = 0.435). At the same time for the ‘More’ button an average of 0.24 sales occurred per tap (2261/9524 = 0.237).
What does all of this tell us? While the ‘Buy’ links have a much higher conversion rate the ‘More’ links create many more click throughs and have higher raw sales numbers2. I do have to say that to me the ‘More’ style links seem a bit disingenuous in that they do not clearly indicate to the user what is going to happen. So, there you have it grasshopper. With great power comes great responsibility. Use these findings as you see fit.
This post is a part of the iDevBlogADay group of Indie development blogs. Thanks to @mysterycoconut for managing such a great site.