使用循环变量在每个循环中获取单词

使用循环变量在每个循环中获取单词

我试图在每个循环中获取这个词。我不知道如何插入iprint $2.

while [ $i -lt 4 ] 
do
    A=$(awk -F_ '{print $2}' <<< 'one_two_test_three')
    echo $A
done

显然,这将输出:

two
two
two
two

我想要的是:

one
two
test
three

我试过:

A=$(awk -F_ '{print $($i)}' <<< 'one_two_test_three')

没用。

答案1

正确的方法是通过( ) 选项将bash/shell变量awk作为参数传递到脚本中:-vvariable

i=1;
while [ $i -lt 5 ]; do
    A=$(awk -v i="$i" -F_ '{ print $i }' <<< 'one_two_test_three')
    echo $A
    ((i++))
done

输出:

one
two
test
three

答案2

不需要 shell 循环来解析数据:

$ awk -F '_' '{ for (i=1; i<=NF; ++i) print $i }' <<<'one_two_test_three'
one
two
test
three

该脚本将输入解析为以_- 分隔的列表并打印每个字段。

较短:

$ awk -F '_' 'BEGIN { OFS="\n" } { $1=$1 } 1' <<< 'one_two_test_three'
one
two
test
three

这将输出字段分隔符设置为换行符,然后在打印记录之前强制重新形成整个记录(插入新的分隔符)。

较短:

$ tr '_' '\n' <<<'one_two_test_three'
one
two
test
three

循环访问数据:

tr '_' '\n' <<<'one_two_test_three' |
while read -r word; do
    printf 'Got "%s"\n' "$word"
done

这样,您就不会多次调用用于解析数据的实用程序。

答案3

假设这些值没有换行符,那么:您的代码只需进行最少的更改即可使其正常工作:shebang 必须是#!/bin/bash(ksh 或 zsh),因为您正在使用<<<.

i=1
while [ "$i" -le 4 ] 
do
    A=$(awk -v var="$i" -F_ '{print $var}' <<< 'one_two_test_three')
    echo "$A"
    i=$((i+1))
done

但是,由于字符串来自 shell,因此可以简化为:

IFS=_ read v1 v2 v3 v4 <<<'one_two_test_three'
printf '%s\n' "$v1" "$v2" "$v3" "$v4"

并使用值数组(可变数量的值):

#!/bin/bash
IFS=_ read -a v <<<'one_two_test_three'
printf '%s\n' "${v[@]}"

如果需要使用更简单的 shell:

#!/bin/sh
IFS=_ read v1 v2 v3 v4  <<-_expandvar_
one_two_test_three
_expandvar_
printf '%s\n' "$v1" "$v2" "$v3" "$v4"

当然,如果不需要设置变量,在脚本中设置 IFS 的值也没有问题:

#/bin/sh
a='one_two_test_three'
IFS=_
set -f
printf '%s\n' $a

请注意,该变量不带引号使用,这可能不安全。

相关内容