linux\bash shell for命令\循环

article/2025/8/2 19:30:14
内容来自《Linux命令行与shell脚本编程大全.第3版 (布鲁姆,布雷斯纳汉)》

for命令

下面是基本格式:

for var in list     # 或者把do也写在这一行:for var in list; do
docommands
done

例如,读取列表:

for test in Aliabma Alska Arizona Arkansas California Colorado
doecho The next state is $test
done

结果输出:

The next state is Aliabma
The next state is Alska
The next state is Arizona
The next state is Arkansas
The next state is California
The next state is Colorado

(test也是一个命令,但$test仍可作为变量名使用)

在最后一次迭代后,$test变量的值会在shell脚本的剩余 部分一直保持有效。它会一直保持最后一次迭代的值(除非你修改了它)。

从变量读取列表
for命令用空格来划分列表中的每个值。如果在单独的数据值中有 空格,就必须用双引号将这些值圈起来。有单引号的,也可以使用转义字符(反斜线)来将单引号转义。

list="Alabama Alaska Arizona Arkansas Colorado"
list=$list" Connecticut"
for state in $list
doecho "Have you ever visited $state?"
done 

(注意,代码还是用了另一个赋值语句向$list 变量包含的已有列表中添加(或者说是拼接)了一个值。这是向变量中存储的已有文本字符串尾部添加文本的一个常用方法。)

结果输出:

Have you ever visited Alabama?
Have you ever visited Alaska?
Have you ever visited Arizona?
Have you ever visited Arkansas?
Have you ever visited Colorado?
Have you ever visited Connecticut?

从命令读取值
生成列表中所需值的另外一个途径就是使用命令的输出。可以用命令替换来执行任何能产生 输出的命令,然后在for命令中使用该命令的输出。

file="states"
for state in $(cat $file)
doecho "Visit beautiful $state"
done
$ cat states
Alabama
Alaska
Arizona
Arkansas
Colorado
Connecticut
Delaware
Florida
Georgia

(上面的例子将文件名赋给变量,文件名中没有加入路径。这要求文件和脚本位于同 一个目录中。如果不是的话,你需要使用全路径名(不管是绝对路径还是相对路径)来引用文件位置。这个例子在命令替换中使用了cat命令来输出文件states的内容。)

结果输出:

Visit beautiful Alabama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticut
Visit beautiful Delaware
Visit beautiful Florida 

你会注意到states文件中每一行有一个州,而不是通过空格分隔的。for命令仍然以每次一行的方式遍历了cat命令的输出。但这并没有解决数据中有空格的问题。如果你列出了一个名字中有空格的州,for命令仍然会将每个单词当作单独的值。

造成这个问题的原因是特殊的环境变量IFS,叫作内部字段分隔符(internal field separator)。 IFS环境变量定义了bash shell用作字段分隔符的一系列字符。默认情况下,bash shell会将下列字 符当作字段分隔符: 空格 制表符 换行符

如果bash shell在数据中看到了这些字符中的任意一个,它就会假定这表明了列表中一个新数据字段的开始。在处理可能含有空格的数据(比如文件名)时,这会非常麻烦,就像你在上一个脚本示例中看到的。

要解决这个问题,可以在shell脚本中临时更改IFS环境变量的值来限制被bash shell当作字段 分隔符的字符。例如,如果你想修改IFS的值,使其只能识别换行符,那就必须这么做:

IFS=$'\n' 

将这个语句加入到脚本中,告诉bash shell在数据值中忽略空格和制表符。

比如:

file="states"
IFS=$'\n'
for state in $(cat $file)
doecho "Visit beautiful $state"
done 

在state文件末尾添加三个州名:

New York
New Hampshire
North Carolina

结果输出:

Visit beautiful Alabama
Visit beautiful Alaska
Visit beautiful Arizona
Visit beautiful Arkansas
Visit beautiful Colorado
Visit beautiful Connecticut
Visit beautiful Delaware
Visit beautiful Florida
Visit beautiful Georgia
Visit beautiful New York
Visit beautiful New Hampshire
Visit beautiful North Carolina

警告:

在处理代码量较大的脚本时,可能在一个地方需要修改IFS的值,然后忽略这次修改,在
脚本的其他地方继续沿用IFS的默认值。一个可参考的安全实践是在改变IFS之前保存原
来的IFS值,之后再恢复它。
这种技术可以这样实现:IFS.OLD=$IFSIFS=$'\n'<在代码中使用新的IFS值>IFS=$IFS.OLD
这就保证了在脚本的后续操作中使用的是IFS的默认值。

还有其他一些IFS环境变量的绝妙用法。假定你要遍历一个文件中用冒号分隔的值(比如在 /etc/passwd文件中)。你要做的就是将IFS的值设为冒号。

IFS=: 

如果要指定多个IFS字符,只要将它们在赋值行串起来就行。

IFS=$'\n':;" 

这个赋值会将换行符、冒号、分号和双引号作为字段分隔符。如何使用IFS字符解析数据没 有任何限制。

用通配符读取目录

最后,可以用for命令来自动遍历目录中的文件。进行此操作时,必须在文件名或路径名中使用通配符。它会强制shell使用文件扩展匹配。如果不知道所有的文件名,这个特性在处理目录中的文件时就非常好用。

在过滤器中使用星号和问号被称为文件扩展匹配(file globbing),指的是使用通配符进行模 式匹配的过程。

如:

ls -l my_s*t

结果输出:

-rw-rw-r-- 1 christine christine 0 May 21 13:25 my_scrapt
-rwxrw-r-- 1 christine christine 54 May 21 11:26 my_script

例如:

for file in /home/rich/.b* /home/rich/badtest
doif [ -d "$file" ]thenecho "$file is a directory"elif [ -f "$file" ]thenecho "$file is a file"elseecho "$file doesn't exist"fi
done 

(for语句首先使用了文件扩展匹配来遍历由通配符生成的文件列表,然后它会遍历列表中的下一个文件。可以将任意多的通配符放进列表中。)

结果输出:

/home/rich/.backup.timestamp is a file
/home/rich/.bash_history is a file
/home/rich/.bash_logout is a file
/home/rich/.bash_profile is a file
/home/rich/.bashrc is a file
/home/rich/badtest doesn't exist

例子中进行了文件比较。test命令允许你测试Linux文件系统上文件和目录的状态。使用中括号可以替代test命令。

在这里插入图片描述

注意,你可以在数据列表中放入任何东西。即使文件或目录不存在,for语句也会尝试处
理列表中的内容。在处理文件或目录时,这可能会是个问题。你无法知道你正在尝试遍
历的目录是否存在:在处理之前测试一下文件或目录总是好的。

还可以使用C 语言风格的for语句。


http://chatgpt.dhexx.cn/article/wynxDydF.shtml

相关文章

linux用while循环输出1到10,Linux Shell系列教程之(十一)Shell while循环 | Linux大学...

摘要 在上一篇Linux Shell系列教程之(十)Shell for循环中&#xff0c;我们已经对Shell 循环语句的for循环进行了介绍&#xff0c;本篇给大家介绍下Shell 中另一种循环语句&#xff1a;Shell while循环。 在上一篇Linux Shell系列教程之(十)Shell for循环中&#xff0c;我们已经…

Linux命令行循环执行shell命令浅谈

本文主要介绍了Linux命令行&#xff0c;循环执行shell命令的相关知识&#xff0c;主要包括死循环&#xff0c;普通计数循环&#xff0c;以及Linux shell循环命令 while死循环的用法,需要的朋友可以参考下 Linux命令行&#xff0c;循环执行shell命令 死循环 命令格式 1 while t…

Linux中shell的循环语句

目录 一、循环语句 1、for循环语句 批量添加未存在的用户&#xff0c;用户名存放在users.txt文件中&#xff0c;每行一个初始密码均设为123456&#xff0c;新增users.txt 文件&#xff0c;vim users.txt 录入用户 2、while循环语句 通过变量RANDOM获得1-999随机数,提示用户猜测…

【LinuxShell】Shell编程之循环语句

文章目录 前言一、循环1.循环的作用2.循环和遍历 二、for循环语句1.for语句的用法2.for逻辑结构3.for语句的格式4.echo的用法5.for语句的典型案列 三、while循环语句1.while语句的用法2.while逻辑结构3.while语句的格式4.while语句的典型案例 四、until命令1.until语句的用法2.…

【Linux】:shell循环语句

运行Shell脚本有两种方法&#xff1a; 1、vi test.sh #! /bin/bash #编写内容 运行sh test.sh 2、chmod x ./test.sh #脚本具有执行权限 ./test.sh #执行脚本 if条件判断 单分支if条件&#xff1a; if [ 条件判断式 ]then程序 fi注意&#xff1a;中括号与条件判断式之间有空…

shell脚本循环执行一个linux命令,shell脚本编程之循环语句

在运行脚本时重复执行一系列的命令是很常见的&#xff0c;这时我们就需要使用循环语句来达到这个目的。 一、for命令 格式&#xff1a;for 变量 in 列表&#xff1b;do 循环体 done for命令会遍历列表中的每一个值&#xff0c;并且在遍历完成后退出循环。 列表形式有以下几种&a…

Linuxshell脚本之循环语句

目录 一、循环 1.循环的含义 2.重复运行次数 3.常见的循环命令 4.循环示意图 二、For语句 1.定义 2.表达式 &#xff08;1&#xff09;for循环 &#xff08;2&#xff09;算术for循环 &#xff08;3&#xff09;嵌套 ​ 三、while语句 1定义 2.格式 3.while循…

【Linux】 Shell循环

for循环遍历 { }C语言风格的for 遍历 while 循环 while test测试成立 do命令 donewhile : # 相当于while true until循环 与while 循环相反 until 循环 while test测试不成立 do命令 donecontinue & break 嵌套的时候 if 要和 fi 在一起 do 要和done 在一起 (相邻最…

二、马尔可夫决策过程与贝尔曼方程

这里写目录标题 1 马尔可夫性质2 马尔可夫过程3 马尔可夫奖励过程&#xff08;Markov reward process, MRP&#xff09;3.1 MRP的贝尔曼方程3.2 MRP的贝尔曼方程求解方法3.3 总结 4 马尔可夫决策过程&#xff08;Markov decision process, MDP&#xff09;4.1 MDP状态价值函数贝…

马尔可夫决策过程和贝尔曼方程

马尔可夫决策过程&#xff08;MDP)简介 下一个状态 S t 1 S_{t1} St1​是从概率分布P中得到的&#xff0c;该概率分布P取决于整个历史&#xff0c;因此我们需要考虑从 s 0 s_0 s0​开始到t时刻的状态。马尔可夫是具有马尔可夫性质的随机过程 定义 P [ S t 1 ∣ S t ] P [ …

贝尔曼方程(Bellman Equation)

贝尔曼方程&#xff08;Bellman Equation&#xff09;也被称作动态规划方程&#xff08;Dynamic Programming Equation&#xff09;&#xff0c;由理查贝尔曼&#xff08;Richard Bellman&#xff09;发现&#xff0c;由于其中运用了变分法思想&#xff0c;又被称之为现代变分法…

强化学习:贝尔曼方程(Bellman Equation)

∗ ∗ 重点&#xff1a;状态值、贝尔曼方程 ∗ ∗ **重点&#xff1a;状态值、贝尔曼方程** ∗∗重点&#xff1a;状态值、贝尔曼方程∗∗ return评估策略 在前面概念介绍中&#xff0c;我们知道了可以用 return 来评估一个策略的好坏。如图&#xff0c;有三个不同的策略&…

贝尔曼方程推导

马尔可夫的动态特性&#xff1a; 回报&#xff1a;&#xff08;两种定义&#xff09; 或 &#xff08;折扣率大于等于0小于等于1&#xff0c;折扣率决定了未来收益的现值&#xff09; 状态价值函数&#xff1a;从状态s开始&#xff0c;智能体按照策略π进行决策所获得回报的…

【机器学习】带你轻松理解什么是强化学习中的贝尔曼方程

系列文章目录 第十八章 Python 机器学习入门之强化学习 目录 系列文章目录 前言 一、什么是贝尔曼方程 二、贝尔曼方程为什么有用 三、贝尔曼方程是怎么来的 总结 前言 贝尔曼方程是强化学习中最重要的一个方程式。如果可以计算状态S 的状态动作函数 Q(s,a)&#xff0c…

强化学习/动态规划:贝尔曼方程的解读 Bellman Equation 贝尔曼方程组 / 贝尔曼最优方程

前言&#xff1a; 读书《Reinforcement Learning: An Introduction Second Edition》&#xff0c;读到第三章有限马尔科夫决策过程MDP中&#xff0c;提到了贝尔曼方程的理解。一开始我是有点懵逼的&#xff0c;现在看懂了其意思&#xff0c;在这里解释一下。 贝尔曼方程理解 下…

贝尔曼方程

贝尔曼方程在强化学习中无处不在&#xff0c;对于理解强化学习算法的工作原理是非常必要的。贝尔曼方程让我们可以开始解决MDPs问题。 贝尔曼期望方程 贝尔曼最优方程 将贝尔曼期望方程与贝尔曼最优方程进行对比&#xff0c;可以发现&#xff0c;贝尔曼期望方程是对于某一个给…

【RL】Bellman Equation 贝尔曼方程(动态规划)

参考&#xff1a;蘑菇书-《EasyRL》 本文只是为了方便自己今后的查阅对原文做出的一些概括。 马尔可夫奖励过程MRP 马尔可夫奖励过程是马尔可夫链加上奖励函数&#xff0c;奖励函数R是一个期望&#xff0c;表示到达某一个状态时可以获得多大的奖励。如果状态数是有限的&#x…

3.1 贝尔曼(bellman)方程

假设智能体观测到状态 s 0 s_0 s0​&#xff0c;并且有 N N N个可用action&#xff0c;每个action都会导致另一种状态&#xff0c;及相应的奖励。另外&#xff0c;假设我们知道与状态s0相连的所有状态的价值 V i V_i Vi​。在这种情况下&#xff0c;智能体可以采取的最佳行动是…

强化学习之贝尔曼方程

强化学习 强化学习注重智能体&#xff08;agent&#xff09;与环境之间的交互式学习&#xff1a; 强化学习的数据集不是训练初始阶段就有的&#xff0c;而是来自智能体与环境交互才能获得&#xff1b;强化学习不追求单步决策的最优策略&#xff0c;而是追求与环境交互获得的长…

强化学习笔记:策略评估--贝尔曼方程求解示例

目录 1. 前言 2. MDP模型 3. 求解贝尔曼方程 1. 前言 策略评估&#xff08;Policy Evaluation&#xff09;&#xff0c;简单来说&#xff0c;就是针对某个既定的策略求其状态值函数和动作值函数。求得了状态值函数和动作值函数&#xff0c;事实上就很容易进行不同候补策略之…