Mahsa
Mahsa

Reputation: 207

How to pass awk as an argument of another function

levenshtein is a function that gets two argument, and computes distance between them: I want to remove the first item of both argument using awk then give them to the levenshtien function, but it did not work:

levenshtein  awk '{$1=""; print}' text1  awk '{$1=""; print}' text2

BTW I could not solve my problem trough this link Bash: pass a function as parameter

I am not interested with the following!

awk '{$1=""; print}' text1 > txt1
awk '{$1=""; print}' text2 > txt2
levenshtein txt1 txt2

Upvotes: 2

Views: 2742

Answers (3)

Alex Punnen
Alex Punnen

Reputation: 6224

You may need to use xargs also in case of multiple arguments

https://unix.stackexchange.com/a/387078/121634

Example

kubectl get all --all-namespaces | grep Terminating |  awk 'NR>1 {print $1 " " $2}'  | xargs -n2  sh -c 'kubectl -
n $1 delete $2 --grace-period=0 --force' sh

Upvotes: 1

Dima Chubarov
Dima Chubarov

Reputation: 17159

You could use a shell feature that is called Process substitution whereby the output of a process is used as an argument to a shell script or a shell function.

Vinicius Placco in the comments has shown how this could work in your case

 levenshtein <(awk '{$1=""; print}' text1) <(awk '{$1=""; print}' text2)

Note that this works only on systems that have Named Pipes or a similar mechnanism, that includes all Linux systems.

Some details

This mechanism works as follows. A special file is created by the system that accumulates the output of a command command inside the <( command ) argument. The name of this file is given as a positional argument to levenshtein script.

Another post suggested using Command substitution $( command ) where the entire output of the command command is used to build the argument list for levenshtein.

For instance if the file text1.txt contains the lines

1 love
2 love
3 love 
...

then levenshtein <( awk '{print $1} text1' ) would create a special file /dev/fd/nn and call `

levenshtein /dev/fd/nn

The contents of the file would be the output of awk '{print $1}' text1.

With command substitution levenshtein $( awk '{print $1}' text1) would split the output into individual tokens separated with whitespace and execute

levenshtein love love love

Upvotes: 2

Jorge Bellon
Jorge Bellon

Reputation: 3096

You can use the standard output of a command as an argument for another using $() in bash. This is called command substitution.

levenshtein $(awk '{$1=""; print}' text1) $(awk '{$1=""; print}' text2)

The difference between this and process substitution (in Dimitri's answer) is that you would use $() if your prorgam does not expect a file but text. If the program expects a file path then you are good to go with <(). Example:

cat <(echo hello)

If you want a single awk output to generate multiple arguments, you will need to go with xargs.

awk '{$1=""; print}' text1 text2 | xargs -n2 levenshtein

Upvotes: 4

Related Questions