Linux进阶bash笔记——逐行(和/或逐字段)读取文件(数据流、变量)

Linux进阶bash笔记——逐行(和/或逐字段)读取文件(数据流、变量)

精选文章moguli202024-12-25 11:47:1524A+A-


Parameter

Details

IFS

内部字段分离器

file

文件名/路径

-r

读取时,防止反斜杠解释

-t

从 readarray 读取的每一行中删除尾部换行符

-d

DELIM 继续,直到读取 DELIM 的第一个字符(读取),而不是换行符

1: 逐行循环浏览文件

while IFS= read -r line; do
echo "$line"
done <file

如果文件末尾不包含换行符,则

while IFS= read -r line || [ -n "$line" ]; do
        echo "$line"
done <file

2: 逐字段循环查看命令输出

假设字段分隔符为 :

while IFS= read -d : -r field || [ -n "$field" ];do
        echo "**$field**"
done < <(ping google.com)

或者用管道:

ping google.com | while IFS= read -d : -r field || [ -n "$field" ];do
        echo "**$field**"
done

3: 将文件行读入数组

readarray -t arr <file

或者用循环:

arr=()
while IFS= read -r line; do
        arr+=("$line")
done <file

4: 将字符串读入数组

var='line 1
line 2
line3'
readarray -t arr <<< "$var"

或者用循环:

arr=()
while IFS= read -r line; do
        arr+=("$line")
done <<< "$var"

5: 逐行循环浏览字符串

var='line 1
line 2
line3'
while IFS= read -r line; do
        echo "-$line-"
done <<< "$var"

或者用循环:

readarray -t arr <<< "$var"
for i in "${arr[@]}";do
        echo "-$i-"
done

6: 逐行循环查看命令输出

while IFS= read -r line;do
        echo "**$line**"
done < <(ping google.com)

或者用管道:

ping google.com |
while IFS= read -r line;do
        echo "**$line**"
done

7: 逐字段读取文件

假设文件中的字段分隔符为 :(冒号)。

while IFS= read -d : -r field || [ -n "$field" ]; do
        echo "$field"
done <file

文件内容:

first : se
con
d:
Thi rd:
Fourth

输出结果是

**first **
** se
con
d**
**
Thi rd**
**
Fourth
**

8: 逐字段读取字符串

假设字段分隔符为 :

var='line: 1
line: 2
line3'
while IFS= read -d : -r field || [ -n "$field" ]; do
        echo "-$field-"
done <<< "$var"

输出:

-line-
- 1
line-
- 2
line3
-

9: 将文件字段读入数组

假设字段分隔符为 :

arr=()
while IFS= read -d : -r field || [ -n "$field" ]; do
        arr+=("$field")
done <file

10: 将字符串的字段读入数组

假设字段分隔符为 :

var='1:2:3:4:
newline'
arr=()
while IFS= read -d : -r field || [ -n "$field" ]; do
        arr+=("$field")
done <<< "$var"
echo "${arr[4]}"

输出:

newline

11: 逐行逐字段读取文件 (/etc/passwd)。

#!/bin/bash
FILENAME="/etc/passwd"
while IFS=: read -r username password userid groupid comment homedir cmdshell
do
        echo "$username, $userid, $comment $homedir"
done < $FILENAME

在 unix 密码文件中,用户信息是逐行存储的,每行由一个用户的信息组成,以冒号(:)字符分隔。在本示例中,在逐行读取文件时,也使用冒号字符作为分隔符将文件行分割成不同的字段,IFS 的值即表示了这一点。

输入示例

mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologin
webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin

输出示例

mysql, 27, MySQL Server /var/lib/mysql
pulse, 497, PulseAudio System Daemon /var/run/pulse
sshd, 74, Privilege-separated SSH /var/empty/sshd
tomcat, 91, Apache Tomcat /usr/share/tomcat6
webalizer, 67, Webalizer /var/www/usage

要逐行读取并将整行内容分配给变量,下面是示例的修改版。请注意,这里只提到了一个变量名line

#!/bin/bash
FILENAME="/etc/passwd"
while IFS= read -r line
do
        echo "$line"
done < $FILENAME

输入示例

mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologin
webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin

输出示例

mysql:x:27:27:MySQL Server:/var/lib/mysql:/bin/bash
pulse:x:497:495:PulseAudio System Daemon:/var/run/pulse:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
tomcat:x:91:91:Apache Tomcat:/usr/share/tomcat6:/sbin/nologin
webalizer:x:67:67:Webalizer:/var/www/usage:/sbin/nologin



您的每一次点赞、分享和评论都是我前进的动力。在这个快速变化的科技世界中,每一步的探索都充满了无限可能。感谢您跟随我的教程,一起揭开了各类技术的秘密面纱。我相信,知识的力量在于分享,而创新的火花在交流中迸发。如果您对这篇文章感到兴奋,对科技的奥秘充满好奇,那么请关注并成为粉丝! 我将持续为您带来实用的教程内容。让我们共同成长,我们下一篇文章见,期待与您在知识的海洋中再次相遇!

点击这里复制本文地址 以上内容由莫古技术网整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

莫古技术网 © All Rights Reserved.  滇ICP备2024046894号-2