다음 루프의 출력을 열에 인쇄하고 싶습니다. 누구든지 이것을 제안할 수 있습니까?
#!/bin/bash
DATE=`date "+%d-%m-%Y_%H-%M-%S"`
### Find User from Server with Expiry Date
for i in `cat /home/sandeepj/Project_user_count/serverlist2`;
do
echo -e "**********"
echo -e "$i"
ssh sandeepj@${i} "awk -F\: '{print \$1}' /etc/passwd"
done >> /tmp/user_count.txt
현재 출력:
**********
10.25.59.3
root
bin
daemon
adm
lp
sync
**********
10.25.59.13
root
bin
daemon
adm
lp
sync
예상 출력:
********** **********
10.25.59.3 10.25.59.13
root root
bin bin
daemon daemon
adm adm
lp lp
sync sync
내 목표는 위의 형식을 달성하는 것입니다.
답변1
만약 당신이 대신
>> /tmp/user_count.txt
각 서버마다 새 파일이 작성됩니다.
do
(
printf '%s\n%s\n' '**********' "$i"
ssh sandeepj@${i} "awk -F\: '{print \$1}' /etc/passwd"
) > "/tmp/user_count_${i}.txt"
done
이것은 쉬울 것입니다:
paste user_count_*.txt | column -tn
답변2
이것딱딱한문제는 실제로 열별로 출력 형식을 지정하는 것입니다.
분리된 열을 포함하는 기존 파일이 있고 |
여기에 새 열을 추가하려고 한다고 가정합니다. paste
다음과 같이 사용하는 경우
paste -d '|' file newdata
파일의 길이가 기존 파일과 다르면 출력의 열 수가 달라지며 열을 더 추가하면 상황이 더 악화될 수 있습니다. 최종 결과를 올바르게 읽는 것은 어렵습니다.
대신, 여기의 프로그램은 awk
기존 파일을 읽고 표준 입력에서 읽은 데이터를 파일의 새 열에 추가합니다. 출력에는 새 열 데이터에 기존 데이터보다 행이 적거나 많은지 여부에 관계없이 첫 번째 행부터 마지막 행까지 고정된 수의 열이 포함됩니다.
BEGIN { OFS = FS }
FNR == 1 {
# We assume that all lines have the same number of columns.
nf = NF
}
{
# Read new column from stdin (clear col if failing).
if ((getline col <"/dev/stdin") != 1)
col = ""
# Add new column (possibly empty) and print.
$(nf + 1) = col
print
}
END {
# We only need to do something here if the new column
# data is longer than the existing data.
$0 = "" # Clear current line.
# Add data from stdin until there is no more to read.
while ((getline col <"/dev/stdin") == 1) {
$(nf + 1) = col
print
}
}
좋아요, 그러면 이것을 사용하여 파일에 이름이 나열된 여러 서버에 SSH로 연결하고 /etc/passwd
각 서버의 파일에서 사용자를 추출하는 작은 셸 스크립트를 만들어 보겠습니다.
#!/bin/sh
outfile=/tmp/outfile
serverlist=servers.list
tmpfile=$( mktemp )
while read -r server; do
ssh -n "$server" cat /etc/passwd |
cut -d : -f 1 |
{
echo '****************'
printf '%s\n\n' "$server"
cat
} |
awk -F '|' -f append_column.awk "$tmpfile" >"$outfile"
cp "$outfile" "$tmpfile"
done <"$serverlist"
awk -F '|' '{ for (i=1; i<=NF; ++i) $i = sprintf("%-20s", $i); print }' "$tmpfile" >"$outfile"
rm -f "$tmpfile"
append_column.awk
이 답변 상단에 있는 프로그램으로 구성된 파일은 다음과 같습니다 .awk
스크립트는 $serverlist
루프에서 파일을 읽고 파일을 ssh -n
가져오기 위해 호출합니다. 이 옵션은 필수입니다. 그렇지 않으면 루프가 반복될 때 동일한 파일에서 읽혀 집니다./etc/passwd
-n
ssh
ssh
$serverlist
사용자 이름은 를 사용하여 추출됩니다 cut
.
이 { ... }
비트는 짧은 헤더를 출력한 다음 호출을 통해 수정되지 않은 사용자 이름을 전달합니다 cat
.
이 awk
프로그램은 임시 파일(지금까지 수집된 결과가 포함됨)을 읽고 결과 데이터를 다시 임시 파일에 복사하여 출력 파일에 열을 추가하는 데 사용됩니다.
루프가 끝나면 파일에는 원하는 데이터가 분리된 필드로 포함 됩니다 $tmpfile
( 실제로 포함됩니다) . 이 문제를 해결하기 위해 출력 파일의 열을 왼쪽 정렬된 20자 길이의 텍스트 필드로 형식화하는 또 다른 짧은 인라인 스크립트를 호출합니다.$output
|
awk
답변3
다음 방법을 시도해 볼 수 있습니다.
for i in `cat serverlist`
do
echo " "| sed "s/.*/====================================/g"
echo $i
ssh -o 'StrictHostKeyChecking no' $i -A "cat /etc/passwd| awk -F ':' '{print $1}'">$i_host_username_details.txt
done
paste *_host_username_details.txt