如何使用 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
。
使用readarray
或mapfile
将多行读入数组。简单多了。确保在循环中也引用变量扩展。
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
如果你有一个带分隔符的字符串,比方说一个 ,
字符,你可以像这样使用 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
。
使用readarray
或mapfile
将多行读入数组。简单多了。确保在循环中也引用变量扩展。
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