以下命令在一次 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
告诉在运行给出的脚本后打印每个输入“行”(这里,一行是整个文件)-p
。perl
-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