bash - 从字符串更改为数组在 Bash 中无法按预期工作

标签 bash

我想将排序方法的结果放入一个数组中,其中每个单元格都包含一个单词。我试过这段代码,但只有 $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

最佳答案

为了将 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[*]}"

请记住,引用可以解决所有问题。

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

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

对于命令替换,$() 优先于反引号。它们更易读,更易于嵌套使用。

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

关于bash - 从字符串更改为数组在 Bash 中无法按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10663694/

相关文章:

linux - 如何编写任意长的管道链?

linux - awk -F 命令根据第一个匹配的模式进行打印

bash - 递归列出目录中所有文件的视频时长

bash - 如何在 Ubuntu 12.04(稳定)上使用特定用户在启动时运行 bash 脚本

macos - 从 Mac Automator 运行 Shell 脚本

bash - 如何在 bash 中捕获 gitlab-runner 的输出

bash - 在Dockerfile中,RUN/bin/mkdir -p/root/lib/{sh,pl,py,rb}未能按预期完成

linux - unix - 自动确定字段分隔符和记录(EOL)分隔符?

bash - shell 管道的惰性(非缓冲)处理

bash - 条件语句中continue和冒号的区别