linux + ssh + 在一个 ssh 中执行两项任务并打印到 CSV

linux + ssh + 在一个 ssh 中执行两项任务并打印到 CSV

以下命令在一次 ssh 关闭中打印两个值

ssh test01 "hostname && cat  /etc/sysconfig/rhn/rhnsd "


test01
INTERVAL=240

但如何更改语法以打印以下格式: (CSV) ,

 test01,INTERVAL=240

我尝试(但没有达到预期)

ssh test01 "hostname && cat  /etc/sysconfig/rhn/rhnsd " | awk '{print $1","$2}'


test01,
INTERVAL=240,

答案1

您需要做的就是解析命令的输出并将第一个换行符 ( \n) 替换为逗号。这应该有效:

ssh test01 "hostname && cat  /etc/sysconfig/rhn/rhnsd " | 
    perl -00pe 's/\n/,/'

在这里,我们使用perl将整个文件放入内存( )并用逗号-0替换第一个。\n告诉在运行给出的脚本后打印每个输入“行”(这里,一行是整个文件)-pperl-e


awk您不起作用的原因是因为awk运行您在每一行上提供的脚本。您的命令打印两行,这两行都只有一个字段 ,$1因此$2未定义。因此,print $1","$2被扩展到print "test01"","第一行和print "INTERVAL=240"","第二行,结果是

test01,
INTERVAL=240,

一个可行的解决方案awk是:

ssh test01 "hostname && cat  /etc/sysconfig/rhn/rhnsd " | 
    awk '{printf "%s,", $1}' | sed 's/,$//'

这将打印每行的第一个字段,后跟一个逗号。该sed命令只是删除打印的最后一行后的尾随逗号。

要打印整行而不是仅打印一个字段,请使用:

ssh test01 "hostname && cat  /etc/sysconfig/rhn/rhnsd " | 
    awk '{printf "%s,", $0}' | sed 's/,$//'

答案2

下列的特登我的建议是,我添加了一种替代方法sed,我主要是为了完整性而将其包括在内,但是与awk '{printf "%s,", $1}'聚合同时省略新队, 和sed我们正在积极更换换行符,因此当我们想要替换不同的角色时它也适合。这是效率低下尽管。

有问题的命令是ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed ':a;N;s/\n/, /;ba'

这个非常神秘的sed命令:a;N;s/\n/, /;ba如果拆开来看其实非常简单。

sed在一次传递中转换输入(与 ie 相反ed,但ed默认情况下通常不包含)。未修改的 ssh 命令返回:

[me@hostname ~]$ ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D"
05
Debian-76-wheezy-64-minimal
a
s
d
f
d
05/04/16

如果我们添加N;s/\n//我们得到:

[me@hostname ~]$ ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed 'N;s/\n//'
05Debian-76-wheezy-64-minimal
as
df
d05/04/16

N下一个将行输入到模式空间中,如下s/\n//删除新队在模式空间中。这就是为什么我们得到了被删除的线对换行符这里。

现在,如果我们希望将完整输入发送到模式空间,我们需要环形在标签的帮助下。

[me@hostname ~]$ ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed ':a;N;s/\n//;ba'
05Debian-76-wheezy-64-minimalasdfd05/04/16

with:a我们设置一个标签,withba我们无条件跳转到该标签a

那么sed ':a;N;s/\n//;ba' 所做的是:

  • 定义标签a
  • 将下一行追加到模式空间 ( N)
  • 通过发送模式空间s/\n//
  • 跳回到a

一旦没有新行可以N追加,它就会退出到脚本末尾。

为了得到它 CS 我们只需要改变替换:

[me@hostname ~]$ ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed ':a;N;s/\n/, /;ba'
05, Debian-76-wheezy-64-minimal, a, s, d, f, d, 05/04/16

这不是很有效,特别是对于较大的行数,因为模式空间通过我们的替换命令为每一行添加并发送行。在聚合之前替换会更有效,但sed不能这样做。

N如果我们在附加下一行后打印模式空间(只需p在该位置放置一个即可打印当前模式空间),这将变得非常明显。在下面的输出中,每 2 行代表当前模式空间(因为仍然包含 *newline) - 就在用 替换换行符之前s/\n//

[me@hostname] ssh test01 "date +%m && hostname && cat asdfd.txt && date +%D" | sed ':a;N;p;s/\n/, /;ba'
05
Debian-76-wheezy-64-minimal
05, Debian-76-wheezy-64-minimal
a
05, Debian-76-wheezy-64-minimal, a
s
05, Debian-76-wheezy-64-minimal, a, s
d
05, Debian-76-wheezy-64-minimal, a, s, d
f
05, Debian-76-wheezy-64-minimal, a, s, d, f
d
05, Debian-76-wheezy-64-minimal, a, s, d, f, d
05/04/16
05, Debian-76-wheezy-64-minimal, a, s, d, f, d, 05/04/16

答案3

对于您的命令,这将产生预期的输出:

counter=0
ssh test01 "hostname && cat  /etc/sysconfig/rhn/rhnsd " \
  | while read line ; do 
  ((counter++)) 
  if [[ counter -eq 1 ]]; then 
    echo -ne "${line},"
  else
    echo "$line"
  fi
  done

相关内容