script icon indicating copy to clipboard operation
script copied to clipboard

[Feature Request] ExecForEach: Accurately get columns by index

Open wanglong001 opened this issue 2 years ago • 7 comments
trafficstars

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()

wanglong001 avatar Dec 06 '22 09:12 wanglong001

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.

bitfield avatar Dec 06 '22 11:12 bitfield

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}}

wanglong001 avatar Dec 06 '22 13:12 wanglong001

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

bitfield avatar Dec 06 '22 15:12 bitfield

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

wanglong001 avatar Dec 06 '22 15:12 wanglong001

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?

bitfield avatar Dec 06 '22 15:12 bitfield

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()

wanglong001 avatar Dec 06 '22 16:12 wanglong001

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!

bitfield avatar Dec 06 '22 18:12 bitfield