sed:在前一个输出为空时执行替代命令

时间:2018-12-18 21:11:10

标签: bash awk sed whois dig

我想修改dig命令以自动对我在输出中收到的任何A记录进行反向查找。

因此,我创建了以下功能:

dt ()
{
    remove=$(echo $@ |  sed 's^https*^^' | sed 's^[,/*:]^^g' );
    dig any +trace +nocl +nodnssec $remove | sed "s/\($remove.*A\s*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\)/dig -x \2 +short | xargs echo \"\1 ->\"/e"
}

使用此代码,我得到以下输出(仅显示一个记录部分,以避免问题变大):

domain.com.      1200    A        198.54.115.174 -> server224-3.web-hosting.com.

但是,现在我还需要使用从dig输出中获得的IP进行whois查找,但前提是dig -x \2 +short没有给出任何结果(stackoverflow.com可以作为域的一个很好的例子带有不具有PTR的A记录。

我尝试了类似的方法来检查常规host命令的退出代码(因为dig表示即使输出为空,输出仍然成功)并根据结果执行正确的命令:

dig any +trace +nocl +nodnssec "$remove" | sed -e "s/\($remove.*A\s*\([0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\)\)/echo -n \"\1 -> \"; host \2 | grep -q ''; if [ ${PIPESTATUS[0]} -eq 0 ]; then dig -x \2 +short; else whois \2 | grep 'network:Network-Name:';fi; /e"

但是sed似乎会影响${PIPESTATUS[0]}数组的值。

我想在sed中进行这些修改,因为我需要可以随时随地打印行的东西。如果我使用变量并修改它们的输出,则该函数的运行速度会变慢,至少在视觉上会如此。

也许在这里可以使用awk,但是我不确定如何使用此命令编写代码。

有没有办法解决这个问题? sed可以用于此目的还是我应该使用其他工具?谢谢。

1 个答案:

答案 0 :(得分:0)

老式的bash可为您提供各种工具grepawkxargswhile read等。将sede命令一起使用,并在内部检查PIPESTATUS并执行xargs ....,这是不可读的,而且读起来也很长。我不清楚您要做什么,因为一行上发生了太多事情。

dig命令在成功时会导致状态为零-如果“失败”时长度为零,则可以检查其输出。

考虑以下脚本:

dt () {
    remove=$(
        <<<$1 \
        sed 's#^http[s]?://\([^/]*\).*#\1#'
    )
        dig any +trace +nocl +nodnssec "$remove" |
        tr -s '\t' |
        awk -v "remove=${remove}." '{
                if ($1 == remove && $3 == "A") {
                        print
                }
        }' |
        while IFS= read -r line; do
                IFS=$'\t' read -r _ _ _ ip _ <<<"$line"
                if ! dig_result=$(dig -x "$ip" +short); then
                        echo "Dig error" >&2
                        exit 1
                fi
                if [ -z "$dig_result" ]; then
                        printf "%s -> no-result-from-dig\n" "$line"
                else
                        printf "%s -> %s\n" "$line" "$dig_result"
                fi
        done
}
  1. 首先运行dig。请注意,"$remove"被引用了。
  2. 只是预防措施-我将制表符压缩在输出中。
  3. 然后我进行过滤-第一列应该有一个带点的"$remove".,第三列应该是一个"A"
  4. 然后每行(因为有很多)
  5. 我得到了IP地址(好吧,也许ip=$(<<<"$line" cut -f4)会更干净,更简单)。
  6. 我使用IP地址从dig -x获取结果
  7. 如果结果为空,则打印“ no-result-from-dig”;否则,我将打印结果。

运行:

dt stackoverflow.com
dt google.pl

输出:

stackoverflow.com.      300     A       151.101.65.69 -> no-result-from-dig
stackoverflow.com.      300     A       151.101.193.69 -> no-result-from-dig
stackoverflow.com.      300     A       151.101.129.69 -> no-result-from-dig
stackoverflow.com.      300     A       151.101.1.69 -> no-result-from-dig
google.pl.      300     A       216.58.215.67 -> waw02s16-in-f3.1e100.net.

您的命令不起作用的原因是$PIPESTATUS"引号内被引号,因此在运行Shell之前已对其进行了扩展。您应该对$进行转义,以使其为\$PIPESTATUS或将其传递到不带引号的单引号" ... "'$PIPESTATUS'" ... "中。