Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialMathew Kurian
4,698 PointsHow do you run multi-stage commands on Terminal?
So I've been playing around with Terminal on my Macbook and seeing what I could do. I was wondering whether you could take the output one complex command and use it as the input for another.
For example: Say I ran { ls -aFR | grep "." | grep "/" | grep "Witcher" }. This basically looks for hidden directories in your file system and lists them out. If you get like 10 files as the output is there anyway to remove all of them with a single command? Instead of typing out and "rm" followed by each path name?
Mathew Kurian
4,698 PointsI was not aware we could do that. Makes sense though since ">" means we take previous output as input.
3 Answers
Brent Petit
7,860 PointsLet me start by saying, be really-really careful with scripted rm operations. if you don't filter out enough files you'll delete stuff you didn't intend to. That being said, you can start by building the output of grep lines into a single line by piping it to 'xargs'.
ls -aFR | grep "." | grep "/" | grep "Witcher" | xargs
if you wanted to use that line as arguments to rm you could do something like this. With backticks...
rm `ls operation | xargs`
This will evaluate everything between the backticks first, resulting in the string of filenames which will then be used as the argument to rm.
I would also recommend looking at the find command. This can be used to search for files. Then the -exec option can be used to run an rm, or whatever command you desire, against the matching filenames.
Mathew Kurian
4,698 PointsI tried doing it with the "find" command first, but it was hard to use and a little unwieldy. What does "operation" in the second command do? And also is it possible to create an alias of this command? So that every time you type in that "alias" it executes the desired command?
Brent Petit
7,860 PointsSorry if my example wasn't so clear. "Operation" was intended to be shorthand for the ls command you wanted to run. So in your case you would actually run...
rm `ls -aFR | grep "." | grep "/" | grep "Witcher" | xargs`
Of course, I would highly recommend running the ls operation without the rm first to make sure you have the file list you desire.
Mathew Kurian
4,698 PointsHey so I did that, but it treats the whole thing as a single directory. And it says "no such file or directory".
I also tried the "<" operator as Preston said above, but that didn't work either. Am I doing something wrong? Is "xargs" a Linux only command? Cause I'm doing this in Terminal on my Macbook Pro.
Brent Petit
7,860 PointsMake sure you are using backticks ( the key to the left of the 1 key) around your original ls command. It sounds like you were using single and double quotes.
And xargs is present on Macs. Type...
man xargs
and you should see instructions on the xargs command.
blacflame
1,848 PointsI would encourage Brent's statement on using find in stead of other commands. Agreed that it is a bit to get use to, but it extremely useful in the long term.
It'll allow you to first check what you are about to remove then execute.
An example:
find -E ./ -regex "(\.|/|Witcher)" -exec ls -ld {} >> mydelfile \;
# Confirm the list, and now re-run with rm
find -E ./ -regex "(\.|/|Witcher)" -exec rm -rf {} \;
The above is just an example and likely does not find the exact files you re looking for. The -E provides extended regex capabilities.
Mathew Kurian
4,698 PointsCan you please explain your command? I don't understand what regex is, or the "-exec" option, ld, and the {}.
Preston Skaggs
11,818 PointsPreston Skaggs
11,818 PointsHave you tried using that command as input for rm? something like: rm < ls -aFR | grep "." | grep "/" | grep "Witcher"