Live data from Hacker News

Bash patterns I use weekly

will-keleher.com

41–50 of 115 posts

Re: Bash patterns I use weekly

#41
We need a simpler regex format. One that allows easy searching and replacing in source code. Of course, some IDE's already to that pretty well, but I'd like to be able to do it from the command line with a stand alone tool I can easily use in scripts.

The simplest thing I know that is able to do that is coccinelle, but even coccinelle is not handy enough.

Re: Bash patterns I use weekly

#42

We need a simpler regex format. One that allows easy searching and replacing in source code. Of course, some IDE's already to that pretty well, but I'd like to be able to do it from the command line with a stand alone tool I can easily use in scripts. The simplest thing I know that is able to do that is coccinelle, but even coccinelle is not handy enough.

It's not perfect but I like sed for this.

Re: Bash patterns I use weekly

#43

I've always had trouble getting `for` loops to work predictably, so my common loop pattern is this: grep -l -r pattern /path/to/files | while read x; do echo $x; done or the like. This uses bash read to split the input line into words, then each word can be accessed in the loop with variable `$x`. Pipe friendly and doesn't use a subshell so no unexpected scoping issues. It also doesn't require futzing around with arr…

For me I always used for loops and only recently (after a decade of using Linux daily) have learned about the power of piped-loops. It’s strange to me you are more comfortable with those than for loops, but I think it does make sense as you’re letting a program generate the list to iterate over. A pain point in for loops is getting that right, e.g. there isn’t a good way to iterate over files with spaces in them usin…

> A pain point in for loops is getting that right, e.g. there isn’t a good way to iterate over files with spaces in them using a for loop

If those files came as arguments, you can use a for-loop as long as they're kept in an array:

  for f in "${files[@]}";
That handles even newlines in the filenames, while I'm not sure if you can handle that with a while-read-loop. IFS=$'\0' doesn't seem to cut it.

for-loops seem preferable for working with filenames. If a command is generating the list, then something like `xargs -0` is preferable.

Re: Bash patterns I use weekly

#44
post #31

> 1. Find and replace a pattern in a codebase with capture groups > git grep -l pattern | xargs gsed -ri 's|pat(tern)|\1s are birds|g' Or, in IDEA, Ctrl-Shift-r, put "pat(tern)" in the first box and "$1s are birds" in the second box, Alt-a, boom. Infinitely easier to remember, and no chance of having to deal with any double escaping.

Using an IDE kind of handicaps you to only working with your IDE though. The shell works everywhere for every use case.

Re: Bash patterns I use weekly

#45

We need a simpler regex format. One that allows easy searching and replacing in source code. Of course, some IDE's already to that pretty well, but I'd like to be able to do it from the command line with a stand alone tool I can easily use in scripts. The simplest thing I know that is able to do that is coccinelle, but even coccinelle is not handy enough.

I think what we really need is one regex format. You have POSIX, PCRE, and also various degrees of needing to double-escape the slashes to get past whatever language you're using the regex in. Always adds a large element of guesswork even when you are familiar with regular expressions.

Re: Bash patterns I use weekly

#46

I want to like this, but the for loop is unnecessarily messy, and not correct. for route in foo bar baz do curl localhost:8080/$route done That's just begging go wonky. Should be stuff="foo bar baz" for route in $stuff; do echo curl localhost:8080/$route done Some might say that it's not absolutely necessary to abstract the array into a variable and that's true, but it sure does make edits a lot easier. And, the orig…

These are the types of stuff you typically run on the fly in the command line, not full blown scripts you intended to be reused and shared.

Here's a few examples from my command history:

  for ((i=0;i
Hell if I know what they do now, they made sense when I ran them. If I need them again, I'll type them up again.

Re: Bash patterns I use weekly

#47
post #31

> 1. Find and replace a pattern in a codebase with capture groups > git grep -l pattern | xargs gsed -ri 's|pat(tern)|\1s are birds|g' Or, in IDEA, Ctrl-Shift-r, put "pat(tern)" in the first box and "$1s are birds" in the second box, Alt-a, boom. Infinitely easier to remember, and no chance of having to deal with any double escaping.

Using an IDE kind of handicaps you to only working with your IDE though. The shell works everywhere for every use case.

That particular IDE works on Windows though… no idea how to use Powershell…

Re: Bash patterns I use weekly

#48

> git bisect is the "real" way to do this, but it's not something I've ever needed uh, yeah, you did need it, that's why you came up with "2. Track down a commit when a command started failing". Seriously though, git bisect is really useful to track down that bug in O(log n) rather than O(n).

For the given command, if the assumption is the command failed recently, it's likely faster than bisect. You can start it and go grab a coffee. It's automatic.

I wish my usage of bisect were that trivial, though. Usually I need to find a bug in a giant web app. Which means finding a good commit, doing the npm install/start dance, etc. for each round.

Re: Bash patterns I use weekly

#49

I've always had trouble getting `for` loops to work predictably, so my common loop pattern is this: grep -l -r pattern /path/to/files | while read x; do echo $x; done or the like. This uses bash read to split the input line into words, then each word can be accessed in the loop with variable `$x`. Pipe friendly and doesn't use a subshell so no unexpected scoping issues. It also doesn't require futzing around with arr…

For me I always used for loops and only recently (after a decade of using Linux daily) have learned about the power of piped-loops. It’s strange to me you are more comfortable with those than for loops, but I think it does make sense as you’re letting a program generate the list to iterate over. A pain point in for loops is getting that right, e.g. there isn’t a good way to iterate over files with spaces in them usin…

You can also have your script change the bash file seperator.

https://bash.cyberciti.biz/guide/$IFS

Something I wish I'd learned 23 years ago instead of 3 years ago :(

Re: Bash patterns I use weekly

#50
post #36

I've always had trouble getting `for` loops to work predictably, so my common loop pattern is this: grep -l -r pattern /path/to/files | while read x; do echo $x; done or the like. This uses bash read to split the input line into words, then each word can be accessed in the loop with variable `$x`. Pipe friendly and doesn't use a subshell so no unexpected scoping issues. It also doesn't require futzing around with arr…

> I've always had trouble getting `for` loops to work predictably, so my common loop pattern is this: The problem with the pipe-while-read pattern is that you can't modify variables in the loop, since it runs in a subshell.

BTW you can make it work in bash by setting shopt -s lastpipe. It runs the last part of the pipeline in the main shell, so the mutation variables of will persist.

Both OSH and zsh behave that way by default, which was tangential to a point in the latest release notes https://news.ycombinator.com/item?id=29292187

Another trick I've seen in POSIX shell is to add a subshell after the pipeline until the last time you want to read the variable. Like

    cat foo.txt | ( while read line; do
      f=$line
    done

    echo "we're still in the subshell f=$f"
    )
Post reply on HN