bash - 从 linux 中的循环中的字符串中提取特定字符

标签 bash shell awk

这是一个新的进一步的问题,基于: Output the result of each loop in different columns .

但是因为是新题,所以不用看链接里的题,下面我会把新题说清楚。

money.txt 文件有两列:(姓名和金钱)

Mary 13
Lucy 8
Jack 20

range.txt 文件包含三列:(fruit、min_value 和 max_value)

apple 10 15
banana 7 12
orange 17 22
blueberry 14 22

我的目的是测试 money.txt 文件中的钱是否在 range.txt 中的 min_value 和 max_value 之间。如果是,打印出range.txtfruit的第(max_value - money)个字符,如果不是, 输出 "x"

例如Marymoney.txt中是1313在min_value和max_value中applemax_value - money 值为 15 - 13 = 2,所以应该打印出apple的第2个字符,即p

预期结果是:(第 4 列是 Mary,第 5 列是 Lucy,第 6 列是 Jack)

apple 10 15 p x x
banana 7 12 x a x
orange 17 22 x x r
blueberry 14 22 x x l

在@ocurran 的帮助下,我尝试了:

# load prices by index to maintain read order
awk 'FNR == NR {
    money[names++]=$2
    next
}
# save max index to avoid using non-standard length(array)
END {
    names=NR
}
{
 l = $1 " " $2 " " $3
 for (i=0; i < names; i++) {
     if ($2 <= money[i] && $3 >= money[i]) {
             fruit=$1
             fruitcharacter=${fruit:($3-money[i]-1):1}
             l = l " " $fruitcharacter
     } else {
             l = l " x"
    }
 }
 print l
}' money.txt range.txt

结果表明:

awk: line 14: syntax error at or near {
awk: line 16: syntax error at or near else
awk: line 19: syntax error at or near }

fruitcharacter=${fruit:($3-money[i]-1):1} 好像不行。但据我所知,我们可以使用 ${string: index: length} 来提取字符串的字符,我不知道为什么它在这种情况下不起作用。你能帮我解决这个问题吗?谢谢。

最佳答案

$ cat tst.awk
NR==FNR { money[NR]=$2; next }
{
    out = $0
    for (i=1; i in money; i++) {
        out = out OFS ( (money[i]>=$2) && (money[i]<=$3) ? substr($1,2,1) : "x" )
    }
    print out
}

$ awk -f tst.awk money.txt range.txt
apple 10 15 p x x
banana 7 12 x a x
orange 17 22 x x r
blueberry 14 22 x x l

如果你想要一些列标题和更好的输出格式:

$ cat tst.awk
NR==FNR { names[NR]=$1; money[NR]=$2; next }
FNR==1 {
    out = "Fruit" OFS "Min" OFS "Max"
    for (i=1; i in names; i++) {
        out = out OFS names[i]
    }
    print out
}
{
    out = $0
    for (i=1; i in money; i++) {
        out = out OFS ( (money[i]>=$2) && (money[i]<=$3) ? substr($1,2,1) : "x" )
    }
    print out
}

$ awk -f tst.awk money.txt range.txt | column -t
Fruit      Min  Max  Mary  Lucy  Jack
apple      10   15   p     x     x
banana     7    12   x     a     x
orange     17   22   x     x     r
blueberry  14   22   x     x     l

关于bash - 从 linux 中的循环中的字符串中提取特定字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39603580/

相关文章:

bash - 如何在 Bash 中将变量设置为命令的输出?

linux - 通过命令行创建具有不同配置文件的 Linux 用户

html - 通过 bash 从 html 中提取信息

bash - ssh脚本不会将控制权返回给父脚本

linux - 如何转义变量以用于 sed?

php - SSH2 修改用户密码

linux - 使用 sed 搜索所有文件的前 3 次和后 3 次出现

用于在 AWK 中捕获具有一系列数字的数字的正则表达式

linux - 如何在 BASH 中按名称排序然后修改日期

linux - awk命令将十六进制转换为带符号的十进制