两个 ssh 输出作为 awk 输入

两个 ssh 输出作为 awk 输入

我有两个正在尝试的远程服务器sshcat一些文件..我想将 ssh 的输出输入到awk命令中。

这就是我所拥有的


ssh username@host1 “cat /tmp/test/*” ssh username@host2 “cat /tmp/test/*” | awk ‘ command ‘

但这不起作用,如果host2目录为空,则输出host1会重复两次。

我在这里做错了什么?

答案1

当心这些弯引号() 某些 Windows 文本编辑器会使用直引号 ('")。您还应该使用's,除非您有某种原因使用"s,例如让变量扩展,请参阅https://mywiki.wooledge.org/Quotes

如果你想要一个 awk 管道,你应该这样做:

{ ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*'; } | awk ' command '

但请考虑这样做,以便 awk 可以区分输入来自哪个命令,以防将来需要这种区分:

awk ' command ' <(ssh username@host1 'cat /tmp/test/*') <(ssh username@host2 'cat /tmp/test/*')

区别如下:

$ seq 3 > file1
$ seq 2 > file2

错误的输出(因为FILENAME总是包含-ARGV[1..2]为空):

$ { cat file1; cat file2; } | awk '
    FILENAME == ARGV[1] { host="host1" }
    FILENAME == ARGV[2] { host="host2" }
    { print host, $0 }
'
 1
 2
 3
 1
 2

错误的输出(因为FILENAMEARGV[1]包含相同的临时文件描述符但ARGV[2]为空):

$ awk '
    FILENAME == ARGV[1] { host="host1" }
    FILENAME == ARGV[2] { host="host2" }
    { print host, $0 }
' <(cat file1; cat file2)
host1 1
host1 2
host1 3
host1 1
host1 2

正确输出:

$ awk '
    FILENAME == ARGV[1] { host="host1" }
    FILENAME == ARGV[2] { host="host2" }
    { print host, $0 }
' <(cat file1) <(cat file2)
host1 1
host1 2
host1 3
host2 1
host2 2

通过这种提供输入的方法获得正确输出的其他可能方法:

$ awk '{print host, $0}' host='host1' <(cat file1) host='host2' <(cat file2)
host1 1
host1 2
host1 3
host2 1
host2 2

答案2

您需要对命令进行分组。最简单的方法是使用花括号将它们分组而不创建子 shell:

{ ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*'; } | 
   awk ' command '

您还可以使用括号,但这有点不优雅,因为它创建了一个您不需要的子 shell。但是,最终结果是相同的,在这种情况下确实不应该产生任何影响。另外,您不需要像;使用时那样添加结尾{ }

( ssh username@host1 'cat /tmp/test/*'; ssh username@host2 'cat /tmp/test/*' ) | 
   awk ' command '

您看到重复输出的原因是因为这两个cat命令都在同一主机上运行。检查localhost用作两个命令的主机时以及运行后的输出set -x

$ ls /tmp/test
file1

$ ssh localhost "cat /tmp/test/*" ssh localhost "cat /tmp/test/*"
+ ssh localhost 'cat /tmp/test/*' ssh localhost 'cat /tmp/test/*'
/tmp/test/file1
/tmp/test/file1
cat: ssh: Is a directory
cat: localhost: No such file or directory
cat: cat: No such file or directory

正如您在上面看到的,这被解释为“ssh localhost cat arg1 arg2 arg3 arg4”,因此运行在(在您的情况下),并作为参数给出,,(catlocalhosthost1/tmp/test/*情况ssh下),然后再次。所以 host1 的内容被ted 两次。localhosthost2cat/tmp/test/*/tmp/testcat

答案3

一种可能的方法是在子 shell 中执行ssh命令并将结果通过管道传输awk

(ssh username@host1 "cat /tmp/test/*"; ssh username@host2 "cat /tmp/test/*" ) | awk ‘ command ‘

相关内容