Splitting strings with IFS


Today I want to discuss splitting strings into tokens or “words”. I previously discussed how to do this with the IFS variable and promised a more in depth discussion. Today, I will make the case on WHY to use IFS to split strings as opposed to using a subshell combined with awk or cut.

I wrote this script which reads the /etc/password file line-by-line and prints the username of any user which has a UID greater than 10 and has the shell of /sbin/nologin. Each test function performs this task 10 times to increase the length of the test:

 [root@sandbox ~]# cat ifs-test.sh #!/bin/bash split_words_cut() { # execute 10 times for i in {0..9} do while read line do # get uid id=$(echo $line | cut -d: -f3) if [[ $id -gt 10 ]] then # get shell shell=$(echo $line | echo $line | cut -d: -f7) if [[ \'/sbin/nologin\' == \"$shell\" ]] then # print username echo $line | cut -d: -f1 fi fi done < /etc/passwd done }

split_words_awk() { # execute 10 times for i in {0..9} do while read line do # get uid id=$(echo $line | awk -F: \'{print $3}\') if [[ $id -gt 10 ]] then # get shell shell=$(echo $line | awk -F: \'{print $NF}\') if [[ \'/sbin/nologin\' == \"$shell\" ]] then # print username echo $line | awk -F: \'{print $1}\' fi fi done < /etc/passwd done } split_words_native() { # execute 10 times for i in {0..9} do while read line do oldIFS=$IFS IFS=: set -- $line IFS=$oldIFS # at this point $1 is the username, $3 # is the uid, and $7 is the shell if [[ $3 -gt 10 ]] && [[ \'/sbin/nologin\' == \"$7\" ]] then echo $1 fi done < /etc/passwd done } echo -e \"---Cut---\" time split_words_cut >/dev/null echo -e \"n---Awk---\" time split_words_awk >/dev/null echo -e \"n---Native---\" time split_words_native >/dev/null

As you can see, using the shell itself is about two orders of magnitude faster than using the subshell awk/cut method:

 [root@sandbox ~]# ./ifs-test.sh
\"Reblog

Kill processes that have been running for more than a week

Bookmark this category

Kill processes that have been running for more than a week
$ find /proc -user myuser -maxdepth 1 -type d -mtime +7 -exec basename {} ; | xargs kill -9

\"commandlinefu.com\"

by David Winterbottom (codeinthehole.com)

\"\"
\"\"

\"\"

URL: http://feedproxy.google.com/~r/Command-line-fu/~3/kr_otvdAVxA/kill-processes-that-have-been-running-for-more-than-a-week

Execute mysql command from shell

phpMyAdmin is a very slow application if you want to execute a query on your database. If you know the name of the database then any GUI tool is an overhead. So I have written a one liner shell script to do that for me 🙂

Here\’s the script:

echo \”select * from table where field like \”%$1%\”\”|mysql -h doamin.com -u amit -p -D amit -r –password=hello

When run with one argument it will execute the sql query directly without asking for password also.