我有以下.txt文件:
Marco
Paolo
Antonio
我想逐行阅读,对于每一行,我想将.txt行值分配给变量。假设我的变量为$name
,则流程为:
$name
=“Marco”$name
$name
=“Paolo”答案 0 :(得分:1195)
以下内容读取逐行作为参数传递的文件:
#!/bin/bash
while IFS= read -r line; do
echo "Text read from file: $line"
done < "$1"
这是用于从循环中的文件读取行的standard form。说明:
IFS=
(或IFS=''
)可防止修剪前导/尾随空格。-r
可防止解释反斜杠转义。如果上述内容保存到文件名为readfile
的脚本中,则可以按如下方式运行:
chmod +x readfile
./readfile filename.txt
如果文件不是standard POSIX text file(=未被换行符终止),则可以修改循环以处理尾随的部分行:
while IFS= read -r line || [[ -n "$line" ]]; do
echo "Text read from file: $line"
done < "$1"
此处,|| [[ -n $line ]]
会阻止最后一行被忽略,如果它不以\n
结尾(因为read
在遇到EOF时返回非零退出代码)。
如果循环内的命令也从标准输入读取,read
使用的文件描述符可能会被其他东西(避免standard file descriptors),例如:
while IFS= read -r -u3 line; do
echo "Text read from file: $line"
done 3< "$1"
(非Bash shell可能不知道read -u3
;请改用read <&3
。)
答案 1 :(得分:288)
我建议您使用代表-r
的{{1}}标记:
read
我引用-r Do not treat a backslash character in any special way. Consider each
backslash to be part of the input line.
。
另一件事是将文件名作为参数。
这是更新的代码:
man 1 read
答案 2 :(得分:125)
使用以下Bash模板应该允许您从文件中一次读取一个值并进行处理。
while read name; do
# Do what you want to $name
done < filename
答案 3 :(得分:66)
import java.awt.Dimension;
import java.awt.EventQueue;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingWorker;
import javax.swing.table.AbstractTableModel;
/**
* @see https://stackoverflow.com/a/34742409/230513
* @see https://stackoverflow.com/a/24762078/230513
*/
public class WorkerTest {
private static final int N = 1_000;
private static final String URL = "jdbc:h2:mem:test";
private static final Random r = new Random();
private void display() {
JFrame f = new JFrame("WorkerTest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
createTestDatabase(N);
JDBCModel model = new JDBCModel(getConnection(), "select * from city");
f.add(new JScrollPane(new JTable(model) {
@Override
public Dimension getPreferredScrollableViewportSize() {
return new Dimension(320, 240);
}
}));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
private static class Row {
int ID;
String name;
}
private static class JDBCModel extends AbstractTableModel {
private final List<Row> data = new ArrayList<>();
private ResultSet rs = null;
private ResultSetMetaData meta;
public JDBCModel(Connection conn, String query) {
try {
Statement s = conn.createStatement();
rs = s.executeQuery(query);
meta = rs.getMetaData();
JDBCWorker worker = new JDBCWorker();
worker.execute();
} catch (SQLException e) {
e.printStackTrace(System.err);
}
}
@Override
public int getRowCount() {
return data.size();
}
@Override
public int getColumnCount() {
try {
return meta.getColumnCount();
} catch (SQLException e) {
e.printStackTrace(System.err);
}
return 0;
}
@Override
public Object getValueAt(int rowIndex, int colIndex) {
Row row = data.get(rowIndex);
switch (colIndex) {
case 0:
return row.ID;
case 1:
return row.name;
}
return null;
}
@Override
public String getColumnName(int colIndex) {
try {
return meta.getColumnName(colIndex + 1);
} catch (SQLException e) {
e.printStackTrace(System.err);
}
return null;
}
private class JDBCWorker extends SwingWorker<List<Row>, Row> {
@Override
protected List<Row> doInBackground() {
try {
while (rs.next()) {
Row r = new Row();
r.ID = rs.getInt(1);
r.name = rs.getString(2);
publish(r);
}
} catch (SQLException e) {
e.printStackTrace(System.err);
}
return data;
}
@Override
protected void process(List<Row> chunks) {
int n = getRowCount();
for (Row row : chunks) {
data.add(row);
}
fireTableRowsInserted(n, n + chunks.size());
}
}
}
private static void createTestDatabase(int n) {
Connection conn = getConnection();
try {
Statement st = conn.createStatement();
st.execute("create table city(id integer, name varchar2)");
PreparedStatement ps = conn.prepareStatement(
"insert into city values (?, ?)");
for (int i = 0; i < n; i++) {
ps.setInt(1, i);
ps.setString(2, (char) ('A' + r.nextInt(26))
+ String.valueOf(r.nextInt(1_000_000)));
ps.execute();
}
} catch (SQLException ex) {
ex.printStackTrace(System.err);
}
}
private static Connection getConnection() {
try {
return DriverManager.getConnection(URL, "", "");
} catch (SQLException e) {
e.printStackTrace(System.err);
}
return null;
}
public static void main(String[] args) {
EventQueue.invokeLater(new WorkerTest()::display);
}
}
答案 4 :(得分:20)
许多人发布了一个过度优化的解决方案。我不认为这是不正确的,但我谦卑地认为,一个不太优化的解决方案将是可取的,让每个人都能轻松理解这是如何工作的。这是我的建议:
#!/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 < "$1"
答案 5 :(得分:17)
使用:
filename=$1
IFS=$'\n'
for next in `cat $filename`; do
echo "$next read from $filename"
done
exit 0
如果您以不同方式设置IFS
,则会得到奇怪的结果。
答案 6 :(得分:9)
如果您需要处理输入文件和用户输入(或stdin中的任何其他内容),请使用以下解决方案:
#!/bin/bash
exec 3<"$1"
while IFS='' read -r -u 3 line || [[ -n "$line" ]]; do
read -p "> $line (Press Enter to continue)"
done
基于the accepted answer和bash-hackers redirection tutorial。
这里,我们打开作为脚本参数传递的文件的文件描述符3,并告诉read
使用此描述符作为输入(-u 3
)。因此,我们将默认输入描述符(0)附加到终端或另一个输入源,能够读取用户输入。
答案 7 :(得分:7)
正确处理错误:
#!/bin/bash
set -Ee
trap "echo error" EXIT
test -e ${FILENAME} || exit
while read -r line
do
echo ${line}
done < ${FILENAME}
答案 8 :(得分:0)
以下内容只会打印出文件内容:
cat $Path/FileName.txt
while read line;
do
echo $line
done
答案 9 :(得分:0)
在bash中使用IFS(内部字段分隔符)工具,定义用于将行分隔为标记的字符,默认情况下包括<< strong> tab > / << strong> space > / < newLine >
步骤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>"
第2步:现在迭代并打印输出:
for line in "${array[@]}"
do
echo "$line"
done
在数组中回显特定的索引:访问数组中的变量:
echo "${array[0]}"