Learning sed or using Claude?
Learning Sed or Using Claude?
I have a favourite linux sys-admin job interview question: you're logged in to a system and it turns out that<br>it doesn't have ls installed. What're five ways to find the contents of the current directory and<br>everything below it? It forces my interviewee to think flexibly about linux. Answers at the bottom of this<br>post...
The older I get, the more I admire thinking flexibly. I use the toolchain that unix gave us all as an<br>inheritance: text streams, filters, a programmable shell. So, I thought I'd ask myself what the tradeoffs are<br>of learning those tools vs learning one of the modern LLM tools. Here's the challenge.
andrew.RssInfo{Title: "PlayTechnique", Dir: "does-not-exist", Description: "Learning to play<br>better."}
This line of code appears a dozen times in my codebase. I changed the Dir parameter from<br>string to []string.
I have two refactoring options: shell or claude.
Our modern shells are programable environments for one-off commands and simple loops.
Knowing how to tackle a refactoring across a single file means that you have to know the right tools. Here's a<br>few options:
Shell
A filter program. There are many text filter programs due to unix's history as a text editing and layout<br>toolchain: sed is the most appropriate here, as the s tream ed itor allows us to edit the<br>file line by line but without needing to open an interactive editor session.
An interactive text editor such as vi or emacs that is notorious for a steep learning curve followed by<br>years of admiration for how well it's designed, or something more user friendly like vs code.
The major scripting languages (perl/ruby/python) all support some method of firing a one-off command that<br>can perform this edit.
Claude
A one-off prompt of the `claude -p` style.
A slash-command defined for either this codebase or defined in your ~/.claude directory.
sed implementation
When I'm implementing sed, I start with a plan, then by getting the matches right. Planning first is a<br>programming practice: if you start fixing a problem by opening a text editor, you're in the wrong game. Start<br>by thinking. I need each instance of<br>Dir: "string" to become Dir: []string{"string"}.
This requires knowing (a) How do I match a line containing the string Dir:, (b) how do I insert a<br>little text before that matched string and after it? (c) a few sed flags. I refine from less specific to more<br>specific. Here's the start (I've made it clear where my match begins and ends; I'm also redacting a lot of<br>output, because I want the example to be clear):
; sed -n 's/Dir:\(.*\)"/BEGINMATCH \1 ENDMATCH/p' rss_feed_test.go<br>rssInfo := andrew.RssInfo{Title: "PlayTechnique", BEGINMATCH ".", Description: "Learning to play better. ENDMATCH}
From here, it's more or less a game, refining the syntax used and the pattern itself, training my mind a<br>little more how to see patterns in text. The key insight I needed to have is that '.' matches every character,<br>whereas '[^"]' matches every character except a quote.
; sed -n 's/Dir: "\([^"]*"\)/Dir: []string{"\1}/p' rss_feed_test.go<br>rssInfo := andrew.RssInfo{Title: "PlayTechnique", Dir: []string{"."}, Description: "Learning to play better."}
There's some arcane syntax in there if you've not seen it before. To figure out one detail of capturing<br>groups, I had to check man regex. Took about six minutes to get right.
The regex syntax needs a little learning and effort. There's no shortcut, but the upside is that the same<br>regex language is implemented in a lot of cli tools and in languages, because the syntax goes all the way back<br>to the original UNIX. Ken Thompson didn't invent regular expressions, but he was one of a few early<br>programmers to actually use them in tools and programs.
claude implementation
claude -p "In the file rss_feed_test.go, please update the argument to Dir in the RssInfo constructor to be an array of strings with the current value as the only member" --allowedTools "Read,Edit,Write,Bash"<br>Updated all four `RssInfo` literals in `rss_feed_test.go` (lines 37, 92, 113, 128) to pass `Dir` as a `[]string` containing the previous value.
Note: `RssInfo.Dir` is still declared as a `string` in the package, so `rss_feed_test.go` won't compile until that field's type is changed too — let me know if you want me to make that change.
Much simpler, yes! But even in a simple task like this, Claude wanted to be sure it said something whacky, so<br>it told me that RssInfo.Dir is of type string when the type is []string. Oh, Claude, never change.
The Claude implementation is obviously much simpler as it's natural language. It cost a handful of tokens. I<br>didn't learn anything, and I was actually misled by my tool, but it was fast, a few seconds to write and 5-10<br>to execute.
The cost of getting convenience without needing to learn the tooling is $20/month. There are cheaper ways to<br>have harnesses, but that's what I pay for Claude Code.
The sed implementation is obviously...