给定一个包含多行的文本文件,我想遍历 Bash 脚本中的每一行。我曾尝试使用
cut
,但 cut
不接受 \n
(换行符)作为分隔符。
这是我正在使用的文件示例:
one
two
three
four
有谁知道我如何在 Bash 中遍历此文本文件的每一行?
我发现自己遇到了同样的问题,这对我有用:
cat file.cut | cut -d$'\n' -f1
或:
cut -d$'\n' -f1 file.cut
使用
cat
连接或显示。这里不需要它。
file="/path/to/file"
while read line; do
echo "${line}"
done < "${file}"
只需使用:
echo -n `cut ...`
这抑制了 最后
cat FILE|while read line; do # 'line' is the variable name
echo "$line" # do something here
done
或(见评论):
while read line; do # 'line' is the variable name
echo "$line" # do something here
done < FILE
所以,已经提供了一些非常好的(可能更好)的答案。但是看看原始问题的措辞,想要使用 BASH for 循环,令我惊讶的是没有人提到更改字段分隔符 IFS 的解决方案。这是一个纯粹的 bash 解决方案,就像 accepted read line
old_IFS=$IFS
IFS='\n'
for field in $(<filename)
do your_thing;
done
IFS=$old_IFS
如果您确定输出将始终以换行符分隔,请使用
head -n 1
代替 cut -f1
(请注意,您在脚本中提到了一个 for 循环,而您的问题最终与脚本无关)。
许多其他答案,包括已接受的答案,不必要地有多行。无需在多行上执行此操作或更改系统上的默认分隔符。
此外,Ivan 提供的带有
-d$'\n'
的解决方案在 Mac OSX 或 CentOS 7 上对我都不起作用。由于他的回答已有四年历史,因此我认为 $
字符的逻辑一定发生了一些变化情况。
read
命令的 While 循环。您不应该使用
cut
对文件中的每一行执行顺序迭代,因为 cut
并非旨在执行此操作。
man cut
您应该将 while 循环与
read -r
命令一起使用,并将标准输入重定向到函数范围内的文件,其中 IFS
设置为 \n
并在使用 -E
时使用 echo
。
processFile() { # Function scope to prevent overwriting IFS globally
file="$1" # Any file that exists
local IFS="\n" # Allows spaces and tabs
while read -r line; do # Read exits with 1 when done; -r allows \
echo -E "$line" # -E allows printing of \ instead of gibberish
done < $file # Input redirection allows us to read file from stdin
}
processFile /path/to/file
为了遍历文件的每一行,我们可以使用 while 循环。这将使我们可以根据需要进行多次迭代。
while <condition>; do
<body>
done
read
命令将来自标准输入的单行存储在变量中。在我们可以使用它从我们的文件中读取一行之前,我们需要重定向标准输入以指向我们的文件。我们可以通过输入重定向来做到这一点。根据 bash 的 man 页面,重定向的语法是 [fd]<file
其中 fd
默认为标准输入(也称为文件描述符 0
)。我们可以将它放在 while 循环之前或之后。
while <condition>; do
<body>
done < /path/to/file
# or the non-traditional way
</path/to/file while <condition>; do
<body>
done
现在我们的文件可以从标准输入读取,我们可以使用
read
。在我们的上下文中,read
的语法是 read [-r] var...
,其中 -r
保留了 \
(反斜杠)字符,而不是将其用作转义序列字符,而 var
是存储变量的名称输入。您可以有多个变量来存储输入的片段,但我们只需要一个变量来读取整行。除此之外,要保留 echo
的任何输出中的任何反斜杠,您可能需要使用 -E
标志来禁用反斜杠转义的解释。如果您有任何缩进(空格或制表符),您需要暂时将IFS
(输入字段分隔符)变量更改为仅"\n"
;通常它被设置为" \t\n"
.
main() {
local IFS="\n"
read -r line
echo -E "$line"
}
main
read
来结束我们的 while 循环?据我所知,只有一种可靠的方法可以确定您何时使用
read
完成读取文件:检查 read
的退出值。如果 read
的退出值是 0
那么我们成功读取了一行,如果它是 1
或更高那么我们到达了 EOF(文件末尾)。考虑到这一点,我们可以在 while 循环的条件部分调用read
。
processFile() {
# Could be any file you want hardcoded or dynamic
file="$1"
local IFS="\n"
while read -r line; do
# Process line here
echo -E "$line"
done < $file
}
processFile /path/to/file1
processFile /path/to/file2
如果我正在执行命令并想剪切输出但它有多行我发现这样做很有帮助
echo $([command]) | cut [....]
这将
[command]
的所有输出放在一行上,这样更容易处理。
迭代文件中记录的最简单方法是通过
for
中的 bash
循环。
#!/bin/bash
echo 'Showing the records in the file';
for i in `cat myfile.txt`; do echo $i; done; # this will show records line by line
echo 'End of the script';
我的意见是“cut”用' ' 作为其默认分隔符。 如果你想使用 cut,我有两种方法:
cut -d^M -f1 file_cut
我通过在 Ctrl+V 后单击 Enter 来制作 ^M。另一种方式是
cut -c 1- file_cut
有帮助吗?