bitfield/script

[Feature Request] ExecForEach: Accurately get columns by index

wanglong001 opened this issue · 7 comments

Example

$ cat t.txt 
column1 ./go.sum
column2 ./go.mod
cat t.txt | awk '{print($2" "$1)}'  #  Swap 1, 2 columns
# ./go.sum column1
# ./go.mod column2
cat t.txt | awk '{system("md5sum "$2"; echo "$1)}' # Column 2 is the input for  md5sum, Column 1 is the  input for echo
# b42820e6479d5c5fa3a8e2daca66d1a1  ./go.sum
# column1
# 9659322eb77f7139a925f7745510c01e  ./go.mod
# column2

This is very flexible function in awk

In script, I except

script.File("t.txt").ExecForEach("md5sum $2; echo $1").Stdout()

I'm not sure how this would work, because pipe stages communicate with one another by a stream of bytes—or lines—not discrete values. Where would $1 and $2 come from?

The best thing to do here might be to write a FilterLine function to compute the arguments $1 and $2 by applying strings.Fields to each line, and then ExecForEach to invoke the shell with your suggested command.

I'm not sure how this would work, because pipe stages communicate with one another by a stream of bytes—or lines—not discrete values. Where would $1 and $2 come from?

The best thing to do here might be to write a FilterLine function to compute the arguments $1 and $2 by applying strings.Fields to each line, and then ExecForEach to invoke the shell with your suggested command.

Go template supports slices accessed by index, and I used this function to achieve awk's columns acquisition, like $1, $2, corresponding to {{ index .Val 0}}, {{index .Val 1}}, Raw input corresponds to {{.Raw}}

Great, so is what you're really asking for that Column should be able to return multiple columns separated by whitespace?

Great, so is what you're really asking for that Column should be able to return multiple columns separated by whitespace?

Yep~ , and the data of multiple columns can be obtained through index

and the data of multiple columns can be obtained through index

I think the program you're suggesting is something like this, isn't it:

script.File("t.txt").ExecForEach("md5sum $2; echo $1")

Is that right?

and the data of multiple columns can be obtained through index

I think the program you're suggesting is something like this, isn't it:

script.File("t.txt").ExecForEach("md5sum $2; echo $1")

Is that right?

It works for me, although not very elegant

script.File("/tmp/test/t.txt").ExecForEach(`bash -c "md5sum {{index .Cols 1}};echo {{index .Cols 0}}"`).Stdout()
// b42820e6479d5c5fa3a8e2daca66d1a1  /tmp/test/go.sum
// a
// 9659322eb77f7139a925f7745510c01e  /tmp/test/go.mod
// b

not works for this

script.File("/tmp/test/t.txt").ExecForEach(`md5sum {{index .Cols 1}};echo {{index .Cols 0}}`).Stdout()

Right, because using the ; character to separate two commands is a bash thing. ExecForEach uses Go's os/exec package, which doesn't have that functionality. Luckily, the shell does!