다음 명령은 하나의 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
:a
라벨을 설정 하면 ba
무조건 라벨로 점프합니다 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