我想将以下循环的输出打印到列中,任何人都可以对此提出建议吗?
#!/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