在Bash中从字符串更改为数组不能按预期工作

时间:2012-05-19 08:37:01

标签: bash

我想将sort方法的结果放入一个数组中,其中每个单元格都包含一个单词。我尝试了这段代码,但只打印了$ file的一部分而且没有排序:

#!/bin/bash
for file in `ls ${1}` ; do
    if [[ ! ($file = *.user) ]] ; then
        continue
    fi

    arr=(`sort -nrk4 $file`)
    echo ${arr[*]}

done

为什么这不起作用?我怎么能这样做?

数据文件:

name1 01/01/1994 a 0
name2 01/01/1994 b 5
name3 01/01/1994 c 2

如果我只运行排序行(sort -nrk4 $ file),这是什么打印:

name2 01/01/1994 b 5
name3 01/01/1994 c 2
name1 01/01/1994 a 0

当我在上面运行2行时,这就是它打印的内容:

 name1 01/01/1994 a 0

1 个答案:

答案 0 :(得分:1)

为了将sort输出的每一行放入其自己的数组元素中,需要将IFS设置为换行符。要输出数组,您需要迭代它。

#!/bin/bash
for file in $1; do
    if [[ ! $file = *.user ]]; then
        continue
    fi

    saveIFS=$IFS
    IFS=$'\n'
    arr=($(sort -nrk4 "$file"))
    IFS=$saveIFS
    for i in "${arr[@]}"
    do
        echo "$i"
    done

done

或者,不要重置IFS,不要使用循环输出,以下命令将输出由换行符分隔的元素,因为IFS的第一个字符用于输出分隔符当*用于引用上下文中的下标时:

echo "${arr[*]}"

请记住,引用修复了所有内容。

请勿在{{1​​}}循环中使用ls。如果for可能包含globbing,那么它应该不加引号。它不是,那么应该引用它以防目录或文件名可能包含空格字符。理想情况下,$1的内容应在此处使用之前进行验证。

比较运算符的优先级高于否定运算符,因此括号不是必需的。

对于命令替换,$1比反引号更受欢迎。它们更易读,更易于嵌套使用。

最后,当扩展变量时,应该引用它。此外,$()几乎总是应该用于下标数组。