bash 逐行读取文件并将值分配给变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10929453/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read a file line by line assigning the value to a variable
提问by Marco
I have the following .txt file:
我有以下 .txt 文件:
Marco
Paolo
Antonio
I want to read it line-by-line, and for each line I want to assign a .txt line value to a variable. Supposing my variable is $name
, the flow is:
我想逐行读取它,并且对于每一行,我想将一个 .txt 行值分配给一个变量。假设我的变量是$name
,流程是:
- Read first line from file
- Assign
$name
= "Marco" - Do some tasks with
$name
- Read second line from file
- Assign
$name
= "Paolo"
- 从文件中读取第一行
- 分配
$name
=“马可” - 做一些任务
$name
- 从文件中读取第二行
- 分配
$name
= "保罗"
回答by cppcoder
The following reads a file passed as an argument line by line:
以下内容逐行读取作为参数传递的文件:
while IFS= read -r line; do
echo "Text read from file: $line"
done < my_filename.txt
This is the standard formfor reading lines from a file in a loop. Explanation:
这是在循环中从文件中读取行的标准形式。解释:
IFS=
(orIFS=''
) prevents leading/trailing whitespace from being trimmed.-r
prevents backslash escapes from being interpreted.
IFS=
(或IFS=''
) 防止前导/尾随空格被修剪。-r
防止反斜杠转义被解释。
Or you can put it in a bash file helper script, example contents:
或者你可以把它放在一个 bash 文件帮助脚本中,示例内容:
#!/bin/bash
while IFS= read -r line; do
echo "Text read from file: $line"
done < ""
If the above is saved to a script with filename readfile
, it can be run as follows:
如果将上述内容保存到带有 filename 的脚本中readfile
,则可以按如下方式运行:
chmod +x readfile
./readfile filename.txt
If the file isn't a standard POSIX text file(= not terminated by a newline character), the loop can be modified to handle trailing partial lines:
如果文件不是标准的 POSIX 文本文件(= 不以换行符终止),则可以修改循环以处理尾随部分行:
while IFS= read -r line || [[ -n "$line" ]]; do
echo "Text read from file: $line"
done < ""
Here, || [[ -n $line ]]
prevents the last line from being ignored if it doesn't end with a \n
(since read
returns a non-zero exit code when it encounters EOF).
在这里,|| [[ -n $line ]]
如果最后一行不以 a 结尾,则防止它被忽略\n
(因为read
在遇到 EOF 时返回非零退出代码)。
If the commands inside the loop also read from standard input, the file descriptor used by read
can be chanced to something else (avoid the standard file descriptors), e.g.:
如果循环内的命令也从标准输入读取,则使用的文件描述符read
可能是其他东西(避免标准文件描述符),例如:
while IFS= read -r -u3 line; do
echo "Text read from file: $line"
done 3< ""
(Non-Bash shells might not know read -u3
; use read <&3
instead.)
(非 Bash shell 可能不知道read -u3
;请read <&3
改用。)
回答by Grzegorz Wierzowiecki
I encourage you to use the -r
flag for read
which stands for:
我鼓励您使用代表以下内容的-r
标志read
:
-r Do not treat a backslash character in any special way. Consider each
backslash to be part of the input line.
I am citing from man 1 read
.
我引用自man 1 read
.
Another thing is to take a filename as an argument.
另一件事是将文件名作为参数。
Here is updated code:
这是更新的代码:
#!/usr/bin/bash
filename=""
while read -r line; do
name="$line"
echo "Name read from file - $name"
done < "$filename"
回答by OneWinged
Using the following Bash template should allow you to read one value at a time from a file and process it.
使用以下 Bash 模板应该允许您一次从文件中读取一个值并对其进行处理。
while read name; do
# Do what you want to $name
done < filename
回答by Gert
#! /bin/bash
cat filename | while read LINE; do
echo $LINE
done
回答by user3546841
Use:
用:
filename=
IFS=$'\n'
for next in `cat $filename`; do
echo "$next read from $filename"
done
exit 0
If you have set IFS
differently you will get odd results.
如果你设置IFS
不同,你会得到奇怪的结果。
回答by Raul Luna
Many people have posted a solution that's over-optimized. I don't think it is incorrect, but I humbly think that a less optimized solution will be desirable to permit everyone to easily understand how is this working. Here is my proposal:
许多人发布了一个过度优化的解决方案。我不认为这是不正确的,但我谦虚地认为,需要一个不太优化的解决方案,让每个人都能轻松理解这是如何工作的。这是我的建议:
#!/bin/bash
#
# This program reads lines from a file.
#
end_of_file=0
while [[ $end_of_file == 0 ]]; do
read -r line
# the last exit status is the
# flag of the end of file
end_of_file=$?
echo $line
done < ""
回答by gluk47
If you need to process both the input file and user input (or anything else from stdin), then use the following solution:
如果您需要同时处理输入文件和用户输入(或来自标准输入的任何其他内容),请使用以下解决方案:
#!/bin/bash
exec 3<""
while IFS='' read -r -u 3 line || [[ -n "$line" ]]; do
read -p "> $line (Press Enter to continue)"
done
Based on the accepted answerand on the bash-hackers redirection tutorial.
Here, we open the file descriptor 3 for the file passed as the script argument and tell read
to use this descriptor as input (-u 3
). Thus, we leave the default input descriptor (0) attached to a terminal or another input source, able to read user input.
在这里,我们为作为脚本参数传递的文件打开文件描述符 3 并告诉read
使用此描述符作为输入 ( -u 3
)。因此,我们将默认输入描述符 (0) 附加到终端或其他输入源,以便能够读取用户输入。
回答by bviktor
For proper error handling:
正确的错误处理:
#!/bin/bash
set -Ee
trap "echo error" EXIT
test -e ${FILENAME} || exit
while read -r line
do
echo ${line}
done < ${FILENAME}
回答by Rekha Ghanate
The following will just print out the content of the file:
以下将只打印出文件的内容:
cat $Path/FileName.txt
while read line;
do
echo $line
done
回答by avivamg
Use IFS (internal field separator) tool in bash, defines the character using to separate lines into tokens, by default includes <tab> /<space> /<newLine>
在bash中使用IFS(内部字段分隔符)工具,定义用于将行分隔成标记的字符,默认包括< tab> /< space> /< newLine>
step 1: Load the file data and insert into list:
第 1 步:加载文件数据并插入到列表中:
# declaring array list and index iterator
declare -a array=()
i=0
# reading file in row mode, insert each line into array
while IFS= read -r line; do
array[i]=$line
let "i++"
# reading from file path
done < "<yourFullFilePath>"
step 2: now iterate and print the output:
第 2 步:现在迭代并打印输出:
for line in "${array[@]}"
do
echo "$line"
done
echo specific index in array: Accessing to a variable in array:
回显数组中的特定索引:访问数组中的变量:
echo "${array[0]}"