我有一个包含多行文本的文本文件,我想在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}"
cut
方法要快得多(时间复杂度为O(n)
),并且更易读。OP在询问如何迭代文件中的每一行。使用 cut
, 要么需要知道文件中的行数,并编写相应数量的cut
语句,要么仍需编写 while 循环,这将使时间复杂度为 O(n + n²)
。 - Andriacat 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
while ... done < file
。 - Kevin只需使用:
echo -n `cut ...`
所以,已经提供了一些非常好的(可能更好的)答案。但是,看着原始问题的措辞,希望使用BASH for循环,让我惊讶的是没有人提到通过更改字段分隔符IFS解决的方法。这是一个纯bash解决方案,就像被接受的read line一样。
old_IFS=$IFS
IFS='\n'
for field in $(<filename)
do your_thing;
done
IFS=$old_IFS
head -n 1
代替cut -f1
(请注意,您在脚本中提到了for循环,而您的问题最终与脚本无关)。-d$'\n'
的解决方案在我的Mac OSX或CentOS 7上也不起作用。由于他的答案已经四年了,我认为在这种情况下$
字符的逻辑肯定已经发生了变化。read
命令的while循环。您不应该使用cut
对文件中的每一行执行顺序迭代,因为cut
没有设计用于此目的。
从每个FILE的选择部分的行打印到标准输出。 — 《
man cut
》
您应该在函数范围内使用带有read -r
命令和将标准输入重定向到文件的while循环,并将IFS
设置为\n
,并在使用echo
时使用-E
。
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
的退出值为0
,则我们成功读取了一行,如果它是1
或更高,则到达了EOF(文件结尾)。有了这个想法,我们可以将对read
的调用放在while循环的条件部分。
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]
的所有输出放在一行中,以便更容易处理。
在编程中,遍历文件记录最简单的方法是使用 bash
中的 for
循环。
#!/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”命令使用'\n'作为默认分隔符。 如果你想使用cut命令,我有两种方法:
cut -d^M -f1 file_cut
我通过按下回车键后再按Ctrl+V来制作^M。另一种方法是
cut -c 1- file_cut
那能帮助吗?