linux awk使用动态列号

gzjq41n4  于 2023-04-29  发布在  Linux
关注(0)|答案(3)|浏览(198)

我想有一个bash函数,打印给定字符串的特定列。
我的解决方案工作正常,但它是冗长的,看起来丑陋的我。
验证码:

#!/bin/bash

function get_ip_segment() {
    case "$2" in
        1)
            printf "%s" "$(echo $1 | awk -F '.' '{print $1}')"
            ;;
        2)
            printf "%s" "$(echo $1 | awk -F '.' '{print $2}')"
            ;;
        3)
            printf "%s" "$(echo $1 | awk -F '.' '{print $3}')"
            ;;
        4)
            printf "%s" "$(echo $1 | awk -F '.' '{print $4}')"
            ;;
        *)
            printf "%s" "$1"
            ;;
    esac
}

IP="12.34.56.78"
echo $IP

echo "$(get_ip_segment $IP 1)"
echo "$(get_ip_segment $IP 2)"
echo "$(get_ip_segment $IP 3)"
echo "$(get_ip_segment $IP 4)"

输出:

12.34.56.78
12
34
56
78

然后,我试图通过删除switch结构来优化这段代码,但它打印了一个意外的输出。

printf "%s" "$(echo $1 | awk -F '.' '{print column_id}' column_id=$2)"

输出:

1
2
3
4

但不知何故,变量替换在awk中不能正确工作。如果我能有一个一行长的函数而不是这个冗长的函数,那就太好了。

yptwkmov

yptwkmov1#

你可以这样做:

get_ip_segment() {
   awk -F. -v c="$2" '{print 1<=c && c<=NF ? $c : $0}' <<<  "$1"
}

IP="12.34.56.78"

get_ip_segment "$IP" 1
12

get_ip_segment "$IP" 2
34

get_ip_segment "$IP" 3
56

get_ip_segment "$IP" 4
78

get_ip_segment "$IP"
12.34.56.78

get_ip_segment "$IP" 5
12.34.56.78
8fq7wneg

8fq7wneg2#

在任何POSIX shell中使用任何awk:

$ cat tst.sh
#!/usr/bin/env bash

get_ip_segment() { awk -v ip="$1" -v seg="$2" 'BEGIN{ split(ip,a,"."); print (seg in a ? a[seg] : ip) }'; }

ip=12.34.56.78
get_ip_segment "$ip" 1
get_ip_segment "$ip" 2
get_ip_segment "$ip" 3
get_ip_segment "$ip" 4
get_ip_segment "$ip" 0
get_ip_segment "$ip" 5
$ ./tst.sh
12
34
56
78
12.34.56.78
12.34.56.78
ar7v8xwq

ar7v8xwq3#

在普通的Bash中:

get_ip_segment() {
    local output=$1
    if [[ $2 = [1-4] ]]; then
        local -a octets
        IFS=. read -ra octets <<< "$output"
        output=${octets[$2 - 1]}
    fi
    printf '%s\n' "$output"
}

ip=12.34.56.78
get_ip_segment "$ip" 1
get_ip_segment "$ip" 2
get_ip_segment "$ip" 3
get_ip_segment "$ip" 4
get_ip_segment "$ip"

在POSIX shell中:

get_ip_segment() {
    case $2 in
        1) output=${1%%.*};;
        2) output=${1#*.}
           output=${output%%.*};;
        3) output=${1%.*}
           output=${output##*.};;
        4) output=${1##*.};;
        *) output=$1
    esac
    printf '%s\n' "$output"
}

ip=12.34.56.78
get_ip_segment "$ip" 1
get_ip_segment "$ip" 2
get_ip_segment "$ip" 3
get_ip_segment "$ip" 4
get_ip_segment "$ip"

相关问题