如何使用 Bash 脚本拆分换行符?

How to split break lines with Bash scripts?

如果你有一个带分隔符的字符串,比方说一个 , 字符,你可以像这样使用 IFS

text=some,comma,separated,text
IFS="," read -ra ADDR <<< "$text"

for i in ${ADDR[@]}
do
    echo $i
done

每个单词将在一个新行中打印。但是如果你获取像 ls 这样的命令的结果,然后尝试在 \n 上拆分它,你不会得到相同的结果:

results=$(ls -la)
IFS="\n" read -ra ADDR <<< "$results"

for i in ${ADDR[@]}
do
    echo $i
done

它只打印2行,而且它们甚至不是文件条目。是

total
36

ls 命令输出的第一行。

有人可以帮忙吗? 如果不是正确的方法,那是怎么回事?

read 通常会一直读到换行为止,除非您使用 -d.

另行告诉它

在这个例子中,我们使用-d $'[=13=]'。这会读取 shell 直到它到达一个空字符(它不会出现在 ls 的输出中)。然后 IFS=$'\n' 导致 shell 在换行处拆分并将每一行分配为数组元素。请注意使用 $'...' 而不是 "..." 来解释转义序列。

results=$(ls -la)

IFS=$'\n' read -ra ADDR -d $'[=10=]' <<< "$results"

for i in "${ADDR[@]}"
do
    echo "$i"
done

最后但同样重要的是,我们必须引用数组的替换和 $i

使用readarraymapfile 将多行读入数组。简单多了。确保在循环中也引用变量扩展。

results=$(ls -la)
readarray -t ADDR <<< "$results"

for i in "${ADDR[@]}"
do
    echo "$i"
done

或跳过 $results 变量:

readarray -t ADDR < <(ls -la)

我不确定您要寻找哪种输出,但我猜您是在寻找分解为标记的每一行。这是一种方法:

/bin/ls -la | while read -ra line
do
    # Whole line
    echo "Line: >${line[@]}<"

    # Break each line into tokens
    for i in ${line[@]}
    do
        echo "- $i"
    done
done

备注

  • 第一行获取 ls -la 的输出并送入 while 循环,将每一行作为一个数组读取
  • 在 while 循环中,我们可以将行作为一个整体来处理,也可以作为单个标记来处理

输出摘录

Line: >-rw-r--r-- 1 haiv staff 142 May 8 10:56 star.md<
- -rw-r--r--
- 1
- haiv
- staff
- 142
- May
- 8
- 10:56
- star.md
Line: >drwxr-xr-x 7 haiv staff 224 May 2 10:26 tailstring<
- drwxr-xr-x
- 7
- haiv
- staff
- 224
- May
- 2
- 10:26
- tailstring