按列打印 SSH 循环输出

按列打印 SSH 循环输出

我想将以下循环的输出打印到列中,任何人都可以对此提出建议吗?

#!/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
    }
}

好的,然后让我们使用它创建一个小型 shell 脚本,它将通过 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(以及$output实际上)将包含您想要作为 - 分隔字段的数据|。为了解决这个问题,我们调用另一个简短的内联awk脚本,将输出文件的列格式化为左对齐、20 个字符长的文本字段。

答案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

相关内容