8 ms·
The Command Line Murders
- networked 11y agoThat was fun. Hint: The file "vehicles" will be easier to deal with using the standard POSIX tools if you translate it into a line-oriented format. Here is a way to do it (in rot13): <iruvpyrf ge '\a' '|' | frq -r 'f/Yvprafr/\aYvprafr/t' > iruvpyrf.ersbeznggrq An alternative solution is to notice that "vehicles" is almost a valid Recutils [1] file. The fix is as simple as frq -r '1,4q;f/Yvprafr Cyngr/YvprafrCyngr:/' iruvpyrf > iruvpyrf.erp You can query the result with `recsel`. (Admittedly, I didn't try this until after solving the mystery.) [1] https://www.gnu.org/software/recutils/#content https://www.gnu.org/software/recutils/#content
- mnw21cam 11y agoWow. Lots of detail. Zip? Seriously?
- teebot 11y agoIf it's a mystery to solve it makes sense not too include too many details :) You should just clone the repo. The zip option is always present on github repos.
- stryk 11y agoWhat's wrong with zip?
- mnw21cam 11y agoAbsolutely nothing. Just a little discordant to see grep et al being discussed in a project packaged as a zip. I suppose people might want to play with this in Windows, although to be honest if you have gone to the trouble to install grep et al, you will have no trouble with tar either.
- irishcoffee 11y agoI'm not usually one to post these, but I can't help it in this care: https://xkcd.com/1168/ https://xkcd.com/1168/
- teekert 11y agotar zxvf! For tar.gz. Never, ever understood why the tar command can't just read the extension and determine the required long list of options needed for successful extraction. Whether I can remember tar xvjpf (for tar.bz2 files) depends on many things, not sure which. To be honest, I like it when I hit a .zip, I can just type "unzip x"... Nice xkcd :)
- Ianvdl 11y agoNewer versions of tar do automatically use the correct procedure based on the extension, just type tar xvf.
- teekert 11y agoWoah, I was stuck in the past! Thanx for the tips!
- andrewaylett 11y agoIt can. $ ls foo.tar.gz $ tar -xf foo.tar.gz $ ls foo.tar.gz my_file.md
- delluminatus 11y agoJust do "tar -xf" for all your file extracting needs. The other command-line parameters are pretty much only needed if you want to override the detected compression format.
- pdkl95 11y agoAll I ever need to remember: atool -x archive.{zip,jar,rar,cab,deb,rpm,tar,tar.{gz,Z,bz2,xz}} (list of supported formats is not complete) With a simple alias, it isn't even necessary to remember the -x alias xx="atool -x" This also protects you from badly made archives that explode hundreds of files into the current directory. All decompression is done in a temporary subdir, which is removed if there was only one file/dir at the top level. For xkcd, see atool's --explain or --simulate options that show you the generated tar/etc commands. http://www.nongnu.org/atool/ http://www.nongnu.org/atool/
- deleted 11y ago[deleted]
- laumars 11y agoIf it bothers you that much then use git instead: git clone https://github.com/Kinto/kinto.git But what you're complaining about has been an option on Github for years.
- the8472 11y agowould have been a great opportunity for gunzip.
- daurnimator 11y agoGreat idea! My path to solution: Get a list of CLUEs: grep -C 3 CLUE crimescene Get a list of the 3 possible suspects based on CLUEs: grep -f <(grep -f memberships/AAA memberships/Delta_SkyMiles | grep -f memberships/Terminal_City_Library | grep -f memberships/Museum_of_Bash_History) -C 3 vehicles | grep -A 6 L337..9 | grep -B 1 -A 4 Honda Then read their interviews: grep <Owner> people tail -n +<line> streets/<street> | head -n 1 less interviews/interview-<interview number> Take your guess :)
- aargh_aargh 11y agoHere's my take on that part (no guessing was necessary): sort AAA Delta_SkyMiles Terminal_City_Library Museum_of_Bash_History | uniq -c -d | sort | grep '^ 4' | cut -d' ' -f8- > ../suspects
- chkuendig 11y agodon't forget to check the interview of the witness, so you get the details of the getaway car. (after checking the clues) grep <Witness> people compare to grep "SEE INTERVIEW" streets/* also, you can add grep -B2 -A3 Blue based on that inverview to your second line. once you check the interviews of the two suspects left, you won't have to guess anymore :)
- daurnimator 11y agoI left out the grep by Blue because Teal is close to Blue.
- xentronium 11y agoWasn't it a bit too short though? I was kinda surprised when I found out I have neither suspect in custody, nor any hard evidence except the one I received initially.
- thegenius2000 11y agoGreat idea doesn't cut it -- this is freaking incredible.
- shabble 11y agoGood fun, I'm going to hope that using ipython still qualifies, and it made things much easier by letting you define functions that join some ad-hoc datasets to look for matches, or read particular files. A similar approach to different puzzles by Peter Norvig[1] Other useful (and perhaps less common) utilities I used were 'q'[2], and the standard unix 'comm(1)'[3] [1] http://nbviewer.jupyter.org/url/norvig.com/ipython/Fred%20Buns.ipynb http://nbviewer.jupyter.org/url/norvig.com/ipython/Fred%20Bu... http://norvig.com/sudoku.html http://norvig.com/sudoku.html [2] https://harelba.github.io/q/ https://harelba.github.io/q/ - sqlite text munging ended up being a bit too clunky though, and I couldn't remember/fix the join syntax to make it worthwhile in teh end. [3] $ comm -12 <(sort memberships/AAA) <(sort memberships/Delta_SkyMiles) > aaa_delta_comm # intersect names in 2 files. Sadly can't handle more than 2 inputs directly though, and assumes pre-sorting.
- d0m 11y agoI think the goal is teaching you unix text commands. So if you use Python it's missing the point. Thoughts?
- navls 11y agoDo what is fun, there is no point
- rcthompson 11y agoSeems equally valid to use it as a tool for learning how to manipulate data in ipython.
- fredley 11y agoThis was great fun! However, it could be called grep murder, as that's the only tool you really need!
- deleted 11y ago[deleted]
- gergoerdi 11y ago`comm -1 -3` (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/comm.html http://pubs.opengroup.org/onlinepubs/9699919799/utilities/co...) is practically made for quickly finding who is a member of all involved groups.
- bgilroy26 11y agoThis is just like SQL joins!
- greggyb 11y agoNope, that would be join.
- bgilroy26 11y agoIndeed you're right. Jonathan Leffler's comment on Stack Overflow discusses the differences --------- There are a couple of differences between comm and join: comm compares whole lines; join compares fields within lines. comm prints whole lines; join can print selected parts of lines. --------- http://stackoverflow.com/questions/7234028/bash-difference-between-join-and-comm http://stackoverflow.com/questions/7234028/bash-difference-b...
- deepnet 11y agoThis was fun and I learned comm to intersect text files. A nicely paced game with a very unusual and fun mechanic that is plausably a part of a detective's skillset.
- Gorgor 11y agoHere is my solution for finding the tall males driving the blue honda with the semi-known licencse plate. I found awk quite suitable. awk 'BEGIN {RS="\n\n"; FS="\n"} $1 ~ /L337.*9$/ && $2 ~ /Honda/ && $3 ~ /Blue/ && $5 ~ /6'\''/ {print $4}' vehicles | cut -d' ' -f2,3 Edit: And to find the intersection between the SkyMiles members and the members of the Museum of Bash History, I used fgrep: grep -Fxf Delta_SkyMiles Museum_of_Bash_History
- tremon 11y agoThat's great, and quite concise. I didn't get further than a sed query to filter the correct paragraphs, and then replace .* with a group filter (WR|DV|P8) to narrow the search: $ sed -rne '/L337.*9$/,/^$/p' vehicles
- Gorgor 11y agoI don’t understand what you gain in replacing .* with (WR|DV|P8) in a second query. Could you elaborate on that?
- tremon 11y agoWell, listing all the number plates that match /L337.*9/ will also return a number of other models and colours than the one we're looking for. So you could make the list smaller by only filtering on the license plates of correct models. But you're right that there's very little gained. The effort of reducing a list of 9 to a list of 4 is better spent on advancing the puzzle :)
- erostrate 11y agoYour first command uses 13 distinct non-alphanumeric characters: '{="\;}$~/.*& It looks more like black magic than code to someone like me who doesn't know awk. It reminds me of these APL/J/K solutions I see on projecteuler.net. I imagine this is what happens when people completely ignore learning curve steepness and optimize for maximum productivity. Very impressive!
- yogiHacks 11y agoprops to the author! This is a great fun and educational game. I'd love to find more like this. Anyone have any recommendations?
- chandraonline 11y agoThis was fun. This was my path to the solution: http://pastebin.com/Px4cLTJV http://pastebin.com/Px4cLTJV
- jmarc 11y agoCORRECT! GREAT WORK, GUMSHOE.
- noobermin 11y agoIs it considered cheating to use files to "save state"? SPOILER: One thing I noticed doing this was that most of the interviews that weren't Alice in Wonderland snippets were less than 3 or 4 lines long. Rather than typing in the same long filtering for loop again and again, I basically outputting the list of "good interviews" to a file which was a `for i in $(cat goodinterviews);...` away. I wasn't sure if using the disk qualifies as just using the command line though... Also, I think more or less (the commands) are cheating just as much as an editor but many associate less as more of a "command line" tool, so the author should specifically forbid it. Also, grep -rn is a godsend in this case, might have made it too easy :) This was quite fun!
- emeraldd 11y agoThis little trick came in very handy cat <file1> <file2> ... | sort | uniq -c | sort -n I have a variant of that which I use to count how often individual words appear in a body of text: cat ${FILES} | tr [:upper:] [:lower:] | sed -r 's/\t/ /g' | sed -r "s/'s//g" | sed -r 's/ /\n/g' | tr -d [:punct:] | sort | uniq -c | sort -n
- emeraldd 11y agoThis little trick came in very handy cat <file1> <file2> ... | sort | uniq -c | sort -n
- swirepe 11y agoI had fun with this, and even though I've been using the terminal for ages, I still learned something new. Specifically $(command -v md5 || command -v md5sum) Does anybody know anything like this, but for sql?
- yes_or_gnome 11y agoTry this: $ type command command is a shell builtin Respectfully-RTM (assuming bash): $ man bash It's a big manpage, so i'll spare you. command [-pVv] command [arg ...] Run command with args suppressing the normal shell function lookup. Only builtin commands or commands found in the PATH are executed. If the -p option is given, the search for command is performed using a default value for PATH that is guaranteed to find all of the standard utilities. If either the -V or -v option is supplied, a description of command is printed. The -v option causes a single word indicating the command or file name used to invoke command to be displayed; the -V option produces a more verbose description. If the -V or -v option is supplied, the exit sta- tus is 0 if command was found, and 1 if not. If neither option is supplied and an error occurred or command cannot be found, the exit status is 127. Otherwise, the exit status of the command builtin is the exit status of command. 'command -v something' just tries to run the 'something' command and fails if it is not found. So, in this instance, try to run 'md5' then try to run 'md5sum'.
- swirepe 11y agoFirst person to solve this on their phone wins.
- gonyea 11y agoMurder She Grepped is the name I would've gone with.
- yes_or_gnome 11y agoFYI. This whole comment is just spoilers. I feel like a homer because I started with the second clue, then the first, and, finally, the (scientifically-proven-unreliable) witness testimony. Starting with Clue #2, get a list of everyone with the set of membership cards. Do this by combining all the lists, sort them together, use uniq to group them ' N FNAME LASTNAME', keep only those with N=4, cut off the cruft, pull each individual's info from the people file, and keep only the males. cat mystery/memberships/{AAA,Delta_SkyMiles,Museum_of_Bash_History,\ Terminal_City_Library} | sort | uniq -c | grep 4 | cut -c 6- \ | xargs -I'{}' grep '{}' mystery/people | sed -ne '/\bM\b/p' With this list of 13 names and addresses (from 5029), I tried to find each one in the street files. HOWEVER, only four of them have existent streets. cat mystery/memberships/{AAA,Delta_SkyMiles,Museum_of_Bash_History,\ Terminal_City_Library} | sort | uniq -c | grep 4 | cut -c 6- \ | xargs -I'{}' grep '{}' mystery/people | sed -ne '/\bM\b/p' \ | cut -f4 | cut -d, -f1 | tr ' ' '_' | xargs -I'{}' \ ls mystery/streets/'{}' 2>/dev/null They are Brian Boyer, Jeremy Bowers, Matt Waite, and Mike Bostock. Following this flaw, I was able to get the answer with four interviews and without consulting clues #1 nor #3. If I were to pursue this train of thought (without the flaw), I would review clue #1 to find suspects over 6' tall (from mystery/vehicles). The list of 13 becomes just six. The four suspects mentioned above and two others; 'Augustin Lozano' and 'Nikolaus Milatz'. Finally, I review Clue #3. I try the following commands because baristas are TERRIBLE at getting people's name correct. grep Annabel mystery/people | sed -ne '/\bF\b' grep Anabel mystery/people | sed -ne '/\bF\b' 'Annabel' pulls up only two names, 'Anabel' pulls up four. 'Annabel Church' ends up being the eyewitness. The crucial piece of info is the partial license plate number. sed -ne '/L337..9/,+6p' mystery/vehicles I'm not command-fu enough to write a better sed command so I do a manual inspection. There are five cars that match the description of a 'Blue Honda'; six if you include 'Teal'. Mr. Bowers, one of my original four suspects, owns a 'Blue Honda', and Mr. Bostock owns the 'Teal'. Anyway. This is just to say that there's more than the prescribed way to solve the game. You could, potentially, solve it with just three interviews 'Annabel', 'Bowers', and 'Bostock'. Or, like me, you could do things ass-backwards.