Automated Power can be addicting, and I've gotten a bit carried away with bash functions recently. Like I got sick of not being able to pass xargs a block of code to run. So I took the each() method idea from ruby See BashEach for the code as the code below has been improved.

each() { 
	cmd="$@"
	while read line; do
		c=$( echo ${cmd} | sed "s/{}/${line}/g" )
		eval ${c}
	done
}

It works for most things, like cleaning out all the users in "root" group.

16326 ~> cat /etc/passwd   | grep :0: | awk -F: '{ print $1 }' | each echo rm -rf /home/{} \; echo userdel {}
rm -rf /home/root
userdel root
rm -rf /home/sync
userdel sync
rm -rf /home/shutdown
userdel shutdown
rm -rf /home/halt
userdel halt
rm -rf /home/operator
userdel operator

Say you wanted to enumerate them, though... you have to wrap the line in single quotes to prevent bash from interpret'ing before each() does (which is why we escaped the semicolon in the previous example).

16365 ~> export i=0; grep :0: /etc/passwd | awk -F: '{print $1}' | each 'i=$(expr $i + 1) ; echo $i {}'
1 root
2 sync
3 shutdown
4 halt
5 operator

The photo came from Cushman. Trivia: Why would you be surprised to see this today? What's happened in the last 50 years? Have guns gotten more dangerous? ;)


The each construct is very nifty. When you were describing it to me on Saturday it felt like something I do all of the time though. And it is, kinda. In straight Bourne shell I usually just do something like this: for user in `cat /etc/passwd | grep :0: | awk -F: '{ print $1 }'` do rm -rf /home/${user} userdel ${user} done I do this kind of stuff interactively all the time. -Jon
Lots of ways to slice things up, with the for loop, you have to backtrack around with your cursor to fill in. With 'each' and 'into', you just continue typing. -- Patrick.