Shell脚本技巧:逐行读取文件与死循环的常用思路
使用while read循环
while IFS= read -r line; do
    echo "Processing: $line"
done < file.txt

解析:

  • IFS=设置内部字段分隔符为空,确保读取时不会因为空格或其他分隔符截断行。
  • read -r会逐行读取内容并存储到变量line中,其中-r参数防止反斜杠被解释为转义字符。
  • < file.txt将文件内容逐行传递给循环。

优缺点:

  • 优点:能够精确逐行读取,保留行中的空格和特殊字符,是最可靠的实现方式。
  • 缺点:需要通过输入重定向读取文件,稍显繁琐。
使用for循环配合cat
for line in $(cat file.txt); do
    echo "Processing: $line"
done

解析:

  • $(cat file.txt)会将文件的所有内容读取到内存中,并按空格和换行符进行分割,逐一传递给for循环。

优缺点:

  • 优点:语法简单,适合小文件或对分割要求不高的场景。
  • 缺点:行中的空格或换行符会导致内容被错误分割,可能无法正确读取多单词的行。
使用mapfile或readarray
mapfile -t lines < file.txt
for line in "${lines[@]}"; do
    echo "Processing: $line"
done

解析:

  • mapfile -t lines会将文件内容逐行读取到数组lines中,-t参数用于移除行尾的换行符。
  • ${lines[@]}通过数组的方式逐行访问内容。

优缺点:

  • 优点:高效简洁,适合需要对文件内容随机访问或同时处理多行的场景。
  • 缺点:需要较新的Bash版本(4.0及以上)。 
使用文件描述符
exec 3< file.txt
while read -r line <&3; do
    echo "Processing: $line"
done
exec 3<&-

解析:

  • exec 3< file.txt将文件绑定到文件描述符3。
  • read -r line <&3从文件描述符3中逐行读取内容。
  • exec 3<&-关闭文件描述符,释放资源。

优缺点:

  • 优点:可以同时操作多个文件描述符,灵活性高。
  • 缺点:代码相对复杂,不够直观。
使用awk逐行处理
awk '{print $0}' file.txt

解析:

  • awk逐行读取文件内容并对每一行执行print $0操作,输出完整行。

优缺点:

  • 优点:语法简洁,适合直接对文件内容进行逐行操作。
  • 缺点:需要学习和掌握awk的使用语法。
使用sed逐行遍历
sed -n 'p' file.txt | while read -r line; do
    echo "Processing: $line"
done

解析:

  • sed -n 'p'逐行输出文件内容。
  • 配合while read实现对文件内容的处理。

优缺点:

  • 优点:可以结合sed的强大功能对内容进行预处理。
  • 缺点:对于简单任务可能显得冗余
死循环的常用实现
使用while true
while true; do
    echo "Running..."
    sleep 1
done
使用for模拟死循环
for ((;;)); do
    echo "Running..."
    sleep 1
done

解析:

  • for ((;;))中的条件部分为空,等价于无限循环。
使用until false
until false; do
    echo "Running..."
    sleep 1
done

解析:

  • until false表示“直到条件为真才退出”,但条件始终为假,因此形成死循环。
使用冒号(:
while :; do
    echo "Running..."
    sleep 1
done
结合逐行读取与死循环的实际应用

以下是逐行读取文件和死循环结合的一个实际应用场景:实时监控日志文件。

tail -n 0 -f logfile.txt | while IFS= read -r line; do
    echo "New log: $line"
done

解析:

  • tail -n 0 -f logfile.txt从文件末尾开始,持续跟踪新增内容。
  • while IFS= read -r line逐行读取新增内容并进行处理。
总结

逐行读取文件:

  • 推荐使用while IFS= read -r或mapfile,能更精准处理复杂内容。
  • 对于简单任务,for line in $(cat file)可以快速实现,但不适合复杂场景。

死循环:

  • 使用while true或while :语法简单直观,是最常见的方式。
  • for ((;;))和until false也是常见替代方案。


shell 判断以abc开头或者bcd结尾
string="abcfasdfasfwrajkfjasdkfjakfj;lk;mljk;lkjgbcd"
beginstr="abc"
endstr="bcd"
if [[ $string =~ ^abc ]]; then
    echo "字符串以abc开头"
fi

if [[ $string =~ ^$beginstr ]]; then
    echo "字符串以abc开头"
fi



if [[ $string =~ bcd$ ]]; then
    echo "字符串以bcd结尾"
fi


if [[ $string =~ $endstr$ ]]; then
    echo "字符串以bcd结尾"
fi
sed 行数为变量,打印两行之间的内容
start_pattern="start"
end_pattern="end"
sed -n "/${start_pattern}/,/${end_pattern}/p" filename