Linux/UNIX:Bash逐行读取文件

时间:2020-01-09 10:45:51  来源:igfitidea点击:

在使用KSH或者BASH shell的Linux或者UNIX-like系统下,如何逐行读取文本文件?
如何在bash脚本中逐行读取文件?
您可以使用while..do..done bash循环在Linux,OSX,* BSD或者类Unix系统上逐行读取文件。

语法:在Bash Unix和Linux shell上逐行读取文件:

  • bash,ksh,zsh和所有其他shell的语法如下,以逐行读取文件
  • while read -r line; do COMMAND; done < input.file
  • 传递给read命令的-r选项可防止反斜杠转义被解释。
  • 在读取命令之前添加IFS =选项,以防止前导/尾随空格被修剪
  • while IFS= read -r line; do COMMAND_on $line; done < input.file

如何在Bash中逐行读取文件

这是您更容易理解的语法:

#!/bin/bash
input="/path/to/txt/file"
while IFS= read -r line
do
  echo "$line"
done < "$input"

输入文件($input)是read命令需要使用的文件的名称。

read命令逐行读取文件,并将每一行分配给$line bash shell变量。
从文件中读取所有行后,bash while循环将停止。
内部字段分隔符(IFS)设置为空字符串,以保留空格问题。
这是一个故障安全功能。

如何使用命令/进程替换逐行读取文件

进程或者命令替换仅意味着运行shell命令并将其输出存储到变量或者将其传递给另一个命令。
语法为:

while IFS= read -r line
do
   ## take some action on $line
  echo "$line"
done < < (command)
 
while IFS= read -r line
do
   ## take some action on $line
  echo "$line"
done < <(ps aux)

使用here字符串

这里的字符串就像这里的文档:

while IFS= read -r line
do
  # take action on $line #
  echo "$line"
done <<< $(command)
 
while IFS= read -r line
do
  # take action on $line #
  echo "$line"
done <<< $(ps aux)
 
## shell script to purge urls from Cloudflare ##
t="10"
I="/home/Hyman/.data/tags.deleted.410"
url=""
while IFS= read -r line
do
        url="$url $line"
done <<<"$(tail -${t} ${I})"
[ "$url" != "" ] && ~/bin/cloudflare.purge.urls.sh "$url"

如何使用读取命令归档描述符

语法很简单:

input="/path/to/file"
while IFS= read -r -uN line
do
  # do something on $line
  echo "$line"
done N< $input

这是一个示例脚本:

while IFS= read -r -u13 line
do 
   echo "$line"
done 13<"${input}"

显示如何逐行读取文件的示例

这里有些例子:

#!/bin/ksh
file="/home/Hyman/data.txt"
while IFS= read line
do
        # display $line or do something with $line
	echo "$line"
done <"$file"

使用bash shell的相同示例:

#!/bin/bash
file="/home/Hyman/data.txt"
while IFS= read -r line
do
        # display $line or do somthing with $line
	printf '%s\n' "$line"
done <"$file"

您还可以按字段读取:

#!/bin/bash
file="/etc/passwd"
while IFS=: read -r f1 f2 f3 f4 f5 f6 f7
do
        # display fields using f1, f2,..,f7
        printf 'Username: %s, Shell: %s, Home Dir: %s\n' "$f1" "$f7" "$f6"
done <"$file"

从bash shell变量读取

假设您要获得Debian或者Ubuntu Linux上所有已安装php软件包的列表,请执行:

# My input source is the contents of a variable called $list #
list=$(dpkg --list php\* | awk '/ii/{print }')
printf '%s\n' "$list"

输出示例:

php-pear
php5-cli
php5-common
php5-fpm
php5-gd
php5-json
php5-memcache
php5-mysql
php5-readline
php5-suhosin-extension

您现在可以从$list中读取并安装软件包:

#!/bin/bash
# BASH can iterate over $list variable using a "here string" #
while IFS= read -r pkg
do
    printf 'Installing php package %s...\n' "$pkg"
    /usr/bin/apt-get -qq install $pkg
done <<< "$list"
printf '*** Do not forget to run php5enmod and restart the server (httpd or php5-fpm) ***\n'

输出示例:

Installing php package php-pear...
Installing php package php5-cli...
Installing php package php5-common...
Installing php package php5-fpm...
Installing php package php5-gd...
Installing php package php5-json...
Installing php package php5-memcache...
Installing php package php5-mysql...
Installing php package php5-readline...
Installing php package php5-suhosin-extension...
*** Do not forget to run php5enmod and restart the server (httpd or php5-fpm) ***