我有一个要运行的命令:
echo "Performing unicornscan on:" $target
unicornscan -Ivv $target:1-65535 | tee enum/uniscan-alltcp.txt
这将产生如下输出:
TCP open 192.168.0.102:443 ttl 128
connected 192.168.103.227:54487 -> 192.168.0.102:161
TCP open 192.168.0.102:161 ttl 128
connected 192.168.103.227:47765 -> 192.168.0.102:80
TCP open 192.168.0.102:80 ttl 128
connected 192.168.103.227:4267 -> 192.168.0.102:1884
TCP open 192.168.0.102:139 ttl 128
sender statistics 963.9 pps with 65536 packets sent total
listener statistics 131180 packets recieved 0 packets droped and 0 interface drops
TCP open http[ 80] from 192.168.0.102 ttl 128
TCP open netbios-ssn[ 139] from 192.168.0.102 ttl 128
TCP open snmp[ 161] from 192.168.0.102 ttl 128
TCP open https[ 443] from 192.168.0.102 ttl 128
TCP open microsoft-ds[ 445] from 192.168.0.102 ttl 128
如何解析此输出以获取逗号分隔列表中的所有IP地址,例如:
80,139,161,443,445
谢谢
答案 0 :(得分:1)
我写了一个脚本,可以解决您的问题。这将打印所有输出。
请按照以下步骤操作:
在文本编辑器中打开answer.bash
(或任何想要给脚本命名的东西)。
键入或粘贴以下内容:
脚本:
#!/bin/bash
# Store the command in a variable for easy changes
# Note: The command is not actually executed until the while loop
COMMAND="unicornscan -Ivv $target:1-65535 | tee enum/uniscan-alltcp.txt"
PORTS=()
# For each line:
while read line; do
# The third token is either IP or protocol name with '['
token=`echo $line | awk '{print $3}'`
last_char_idx=$((${#token}-1))
last_char=${token:$last_char_idx:1}
# Case 1: It is the protocol name
if [[ "$last_char" = "[" ]]; then
# This is a protocol. Therefore, port is token 4
port=`echo $line | awk '{print $4}'`
# Shave off the last character
port=${port::-1}
else
# token is ip:port. Awk out the port
port=`echo $token | awk -F: '{print $2}'`
fi
PORTS+=("$port")
done < <($COMMAND | egrep "^TCP open")
# egrep is used to skip any lines that don't begin with TCP open
# 'tee' should still send full output to file
# Print all the ports we found
for p in "${PORTS[@]}"; do
echo -n "$p, "
done
echo
保存文件。
键入bash answer.bash
。观察您希望的输出(希望如此!)
该脚本使用while
循环逐行浏览命令。每次迭代时,当前行都设置为line
变量。
在while循环中,我使用egrep
获得仅以TCP open
开头的行。我注意到每行的第三个标记要么包含IP:Port值,要么包含协议名称,后跟[
字符。脚本假定后一种情况以[
结尾,并使用awk
从第四个令牌中获取端口名,从而进行相应的处理。如果是IP:端口对,则也可以使用awk
作为字段分隔符的:
。
以这种方式获得的每个端口都存储在PORTS阵列中。在脚本末尾,将打印ports数组的每个值,并产生以下输出:
443, 161, 80, 139, 80, 139, 161, 443, 445,
您可以将此脚本的输出传递到文件或变量中,或将其存储在脚本内部的变量中。
如果您有任何疑问,请告诉我它的工作原理。另外,我还要为过度使用subshell表示歉意。
答案 1 :(得分:0)
尝试类似的东西:
#!/bin/bash
declare -a ary
while read -r line; do
if [[ "$line" =~ \[\ *([0-9]+)\] ]]; then
ary+=("${BASH_REMATCH[1]}")
fi
done < "file.txt"
ifs_bak="$IFS" # back up IFS
IFS=,; list="${ary[*]}"
IFS="$ifs_bak" # retrieve IFS
echo "$list"
[
和]
之间的数值,并为其分配${BASH_REMATCH[1]}
。ary
中。ary
打印为逗号分隔的值。