使用awk的输出运行命令

时间:2022-02-08 13:56:29

I am brand new to shell scripting and cannot seem to figure out this seemingly simple task. I have a text file (ciphers.txt) with about 250 lines, and I would like to use the first column of each line as an argument in a command. Any help would be greatly appreciated!

我是shell脚本编程的新手,似乎无法解决这个看似简单的任务。我有一个大约250行的文本文件(ciphers.txt),我希望在命令中使用每行的第一列作为参数。如有任何帮助,我们将不胜感激!

the command is:

的命令是:

openssl s_client -connect host:port -cipher argument

It works fine when I do one at a time but I do not really want to run the same command 250+ times. Here is my script so far:

当我一次执行一个命令时,它工作得很好,但是我并不想运行相同的命令250多次。到目前为止,我的剧本是这样的:

awk '{command = "openssl s_client -connect localhost:4433 -cipher > results.txt"
print $0 | command}' ciphers.txt

I keep getting an error so I am pretty sure I have a syntax error somewhere. Is the output of awk being appended after -cipher?

我不断地得到一个错误,所以我很确定我有一个语法错误。awk的输出是在-cipher之后附加的吗?

3 个解决方案

#1


51  

Use system from within awk:

awk内部使用系统:

awk '{ system("openssl s_client -connect host:port -cipher " $1) }' ciphers.txt

#2


10  

there are quite a few things wrong with your command. For one you want to use the first column. That's referred to as $1 in awk and not $0 (which would be the whole line). Second, you forgot a semicolon at the end of your definition of command.

你的命令有很多问题。首先要使用第一列。这被称为$1 in awk,而不是$0(这是整条线)。第二,在命令的定义结束时,您忘记了分号。

To actually run the command you can either use system() or a pipe (the latter only makes sense if the command can read from stdin, which openssl in your case won't, I think). The easiest would be something like

要实际运行该命令,您可以使用system()或管道(后者只在命令可以从stdin中读取时才有意义,我认为openssl在您的例子中不会这样)。最简单的是

awk '{cmd="openssl s_client -connect host:port -cipher" $1; system(cmd)}' results.txt

Note, that this will only return the exit status. If you need to capture stdout, you will have to pipe the command through getline.

注意,这将只返回退出状态。如果您需要捕获stdout,您将不得不通过getline来传输命令。

Andreas

安德烈亚斯

PS: Posting the actual error you got, would have helped.

PS:公布你的实际错误,会有帮助的。

#3


7  

The xargs command is specifically for that use case.

xargs命令专门用于那个用例。

awk '{print $0}' <ciphers.txt | xargs -I{} openssl s_client -connect host:port -cipher {} >>results.txt

This version is a bit longer for the example case because awk was already being used to parse out $0. However, xargs comes in handy when you already have a list of things to use and are not running something that can execute a subshell. For example, awk could be used below to execute the mv but xargs is a lot simpler.

这个版本对于示例来说有点长,因为awk已经被用于解析$0。但是,当您已经有一个要使用的东西列表,并且没有运行可以执行子shell的东西时,xargs就派上了用场。例如,awk可以用来执行mv,但是xargs要简单得多。

ls -1 *.txt | xargs -I{} mv "{}" "{}.$(date '+%y%m%d')"

The above command renames each text file in the current directory to a date-stamped backup. The equivalent in awk requires making a variable out of the results of the date command, passing that into awk, and then constructing and executing the command.

上面的命令将当前目录中的每个文本文件重命名为带有日期戳的备份。awk中的等效项需要从date命令的结果中创建一个变量,并将其传递到awk中,然后构造并执行该命令。

The xargs command can also accumulate multiple parameters onto a single line which is helpful if the input has multiple columns, or when a single record is split into recurring groups in the input file.

xargs命令还可以将多个参数累积到一行中,如果输入有多个列,或者当一个记录被分割成输入文件中的循环组时,这将非常有用。

For more on all the ways to use it, have a look at "xargs" All-IN-One Tutorial Guide over at UNIX Mantra.

有关使用它的所有方法的更多信息,请参阅UNIX咒语的“xargs”一体式教程指南。

#1


51  

Use system from within awk:

awk内部使用系统:

awk '{ system("openssl s_client -connect host:port -cipher " $1) }' ciphers.txt

#2


10  

there are quite a few things wrong with your command. For one you want to use the first column. That's referred to as $1 in awk and not $0 (which would be the whole line). Second, you forgot a semicolon at the end of your definition of command.

你的命令有很多问题。首先要使用第一列。这被称为$1 in awk,而不是$0(这是整条线)。第二,在命令的定义结束时,您忘记了分号。

To actually run the command you can either use system() or a pipe (the latter only makes sense if the command can read from stdin, which openssl in your case won't, I think). The easiest would be something like

要实际运行该命令,您可以使用system()或管道(后者只在命令可以从stdin中读取时才有意义,我认为openssl在您的例子中不会这样)。最简单的是

awk '{cmd="openssl s_client -connect host:port -cipher" $1; system(cmd)}' results.txt

Note, that this will only return the exit status. If you need to capture stdout, you will have to pipe the command through getline.

注意,这将只返回退出状态。如果您需要捕获stdout,您将不得不通过getline来传输命令。

Andreas

安德烈亚斯

PS: Posting the actual error you got, would have helped.

PS:公布你的实际错误,会有帮助的。

#3


7  

The xargs command is specifically for that use case.

xargs命令专门用于那个用例。

awk '{print $0}' <ciphers.txt | xargs -I{} openssl s_client -connect host:port -cipher {} >>results.txt

This version is a bit longer for the example case because awk was already being used to parse out $0. However, xargs comes in handy when you already have a list of things to use and are not running something that can execute a subshell. For example, awk could be used below to execute the mv but xargs is a lot simpler.

这个版本对于示例来说有点长,因为awk已经被用于解析$0。但是,当您已经有一个要使用的东西列表,并且没有运行可以执行子shell的东西时,xargs就派上了用场。例如,awk可以用来执行mv,但是xargs要简单得多。

ls -1 *.txt | xargs -I{} mv "{}" "{}.$(date '+%y%m%d')"

The above command renames each text file in the current directory to a date-stamped backup. The equivalent in awk requires making a variable out of the results of the date command, passing that into awk, and then constructing and executing the command.

上面的命令将当前目录中的每个文本文件重命名为带有日期戳的备份。awk中的等效项需要从date命令的结果中创建一个变量,并将其传递到awk中,然后构造并执行该命令。

The xargs command can also accumulate multiple parameters onto a single line which is helpful if the input has multiple columns, or when a single record is split into recurring groups in the input file.

xargs命令还可以将多个参数累积到一行中,如果输入有多个列,或者当一个记录被分割成输入文件中的循环组时,这将非常有用。

For more on all the ways to use it, have a look at "xargs" All-IN-One Tutorial Guide over at UNIX Mantra.

有关使用它的所有方法的更多信息,请参阅UNIX咒语的“xargs”一体式教程指南。