使用 sed 或 awk 映射自定义和任意函数

问题描述 投票:0回答:1

我正在尝试使用命令

sed
awk
以及定义的任意函数(或命令),例如 Bash 脚本。 例如,以下 Bash 脚本
prepend_largest_prime.sh
接受一个字符串作为其第一个参数,并输出 N 以下的较大素数,其中 N 是字符串的长度:

#!/bin/bash

is_prime() {
# Returns 1 if a number is prime, 0 if not
    i=2
    if [ $1 -lt 2 ]
    then
        return 0
    fi
    
    max=`echo "sqrt($1)" | bc`
    while [ $i -le $max ]
    do
        if [ `expr $1 % $i` -eq 0 ]
        then
            return 0
        fi
        i=`expr $i + 1`
    done
    
    return 1
}

largest_prime_under() {
    counter=$1
    is_prime $counter 
    counter_primeQ=$?

    if [[ $counter_primeQ = 1 ]]; then
        echo $counter
        exit 1
    fi
    counter=$[ $counter - 1 ]

    while [[ $counter -gt 0 ]] ; do
        is_prime $counter
        counter_primeQ=$?
        if [[ $counter_primeQ = 1 ]]; then
            echo "$counter"
            exit 1
        fi
        counter=$[ $counter - 1 ]
    done
}

string_length() {
    str="$1"
    n=${#str}
    echo "$n"
}

string_length_num=$(string_length "$1")
largest_prime_under_string=$(largest_prime_under $string_length_num)

echo $largest_prime_under_string $1

此脚本的调用示例可以是:

$ ./prepend_largest_prime.sh 'The quick brown fox jumps over the lazy dog.'
43 The quick brown fox jumps over the lazy dog.

这里传递的字符串有44个字符,44以下较大的素数是43。

这就是我所能做到的一切。它仍然不起作用,并且对于手头的任务来说似乎太复杂了:

cat input_file.txt
The majestic mountains towered over the quaint little beautiful village below.
The serene garden is colorful.
The old oak trees stood tall, their branches reaching towards the sky.
$ sed "s|.*|\"\$(\./prepend_largest_prime.sh '&')\"|" input_file.txt
"$(./prepend_largest_prime.sh 'The majestic mountains towered over the quaint little beautiful village below.')"
"$(./prepend_largest_prime.sh 'The serene garden is colorful.')"
"$(./prepend_largest_prime.sh 'The old oak trees stood tall, their branches reaching towards the sky.')"

对于这个例子,我正在寻找的命令的输出应该是

73 The majestic mountains towered over the quaint little beautiful village below.
29 The serene garden is colorful.
67 The old oak trees stood tall, their branches reaching towards the sky.

我怎样才能实现这个目标? 谢谢!

linux bash awk sed command-line
1个回答
0
投票

我正在尝试使用命令

sed
awk
以及定义的任意函数(或命令),例如,作为 Bash 脚本。

这很尴尬。没有双关语的意思。正如评论中所述,您所描述的内容更适合外壳。或者,

xargs
是专门为此类任务而设计的:

xargs -d '\n' -n1 ./prepend_largest_prime.sh < input.txt

如果您必须通过

awk
sed
驾驶它,那么您确实有选择。 POSIX 没有定义
sed
执行外部命令的方法,但如果您可以依赖 GNU
sed
提供的扩展,那么它的
e
命令就可以使用。您可以将输入行编辑为要执行的命令,然后使用
e
:

执行它
sed "s,^\(.*\)\$,./prepend_largest_prime.sh '\1',; e" input.txt

还有其他方法可以处理细节,但该特定方法使用

s
命令将输入行用单引号括起来,并在前面加上要执行的命令的名称。请注意,如果输入包含单引号,它会中断,尽管您可以多花点功夫来适应它。

awk
版本更标准,更容易阅读,使用其
system()
功能,但思想基本相同。将每个输入行编辑到要执行的 shell 命令中,并将结果传递给
system()
:

awk '{ system("./prepend_largest_prime.sh '" $0 "'") }' < input.txt

与基于

sed
的方法一样,您需要做更多的工作来适应包含单引号字符的输入。

© www.soinside.com 2019 - 2024. All rights reserved.