1. ホーム
  2. スクリプト・コラム
  3. リナックスシェル

シェルスクリプトがテキストファイルを1行ずつ処理する方法

2022-01-05 21:44:29

テキストファイルを一行ずつ処理することがよくありますが、シェルで各行のデータを取得し、その行のデータを処理し、最後に次の行のデータを読み込むというループ処理をどのように行うのでしょうか。以下のように様々な解決策があります。

1. readコマンドで行う。

readコマンドは、標準入力から一行を読み込み、入力行の各フィールドの値を、変数IFS(Internal Field Separator)の文字をセパレータとして、シェル変数に代入する。VariableNameパラメータから最後のフィールドまで、各フィールドの値に代入する。

は、その

readコマンドは、標準入力、または他のファイルディスクリプタからの入力を取得すると、そのデータを標準変数に格納します。

readでファイルを読む場合、readコマンドを呼び出すたびに、ファイルから「一行」のテキストが読み込まれる。

ファイル内に読み取り可能な行がない場合、readコマンドは0以外の状態で終了します。

void APIENTRY glPolygonOffset (GLfloat factor, GLfloat units);

2. awkコマンドで完成

awkは、非常に強力な機能を備えた優れたテキスト処理ツールです。

構文フォーマット:awk [option] 'command' manipulate file

共通のオプションです。-F セパレータを指定、セパレータは""で生じる。

-v: var=value は awk プログラムが始まる前に変数 var に値を指定します、これらの変数の値は awk プログラムの BEGIN fast で使用されます

-f: コマンドラインで awk プログラムを指定する代わりに、その後に awk プログラムを格納するファイルを指定します。

awk を使って、ファイルの各行のデータを読み込んで、各行のデータに対して何らかの処理を行うとともに、各行のデータの各列を個別に処理します。

#include"freeglut.h"
#include<math.h>

GLfloat angle=0.0f;

void myDisplay()
{
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);	

	glPushMatrix();	
	glDisable(GL_POLYGON_OFFSET_FILL);
	glRotatef(angle,0,1,0);

	glColor3f(1,0,0);
	glRectf(-1.5,-1.5,0.5,0.5);
	glEnable(GL_POLYGON_OFFSET_FILL);
	glPolygonOffset(-1.0,-1.0);

	glColor3f(0,1,0);
	glRectf(-0.5,-0.5,1.5,1.5);
	glPolygonOffset(-2.0f,-2.0f);

	glColor3f(0,0,1);
	glLineWidth(3);
	glBegin(GL_TRIANGLES);
	glVertex3f(-1.5,-1.5,0);
	glVertex3f(-1.5,-0.5,0);
	glVertex3f(0.5,0.5,0);
	glEnd();

	glPopMatrix();
	glutSwapBuffers();
}

void Init()
{
	glEnable(GL_DEPTH_TEST);
	glClearColor(1,1,1,1);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(70,1,1,20);
	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(0,0,3,0,0,0,0,0,1,0);
}

void SpecialKey(GLint key,GLint x,GLint y)
{
	if(key==GLUT_KEY_UP||key==GLUT_KEY_LEFT)
	{
		angle-=0.8f;
	}
	if(key==GLUT_KEY_DOWN||key==GLUT_KEY_RIGHT)
	{
		angle+=0.8f;
	}
	myDisplay();
}

int main(int argc, char *argv[])      
{      
	glutInit(&argc, argv); //initialize GLUT  
	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);    
	glutInitWindowPosition(500, 200);      
	glutInitWindowSize(400, 400);      
	glutCreateWindow("OpenGL");   
	Init();   
	glutDisplayFunc(&myDisplay); //callback function   
	glutSpecialFunc(&SpecialKey);
	glutMainLoop(); //continuous display, when the window changes will redraw the graphics  
	return 0;      
}   

1行目のコードでdata.datの各行のデータを出力し、2行目で2列目以降の各行のデータを出力しています。

単にデータやテキストファイルを行単位で読み込んで表示するのであれば、awkコマンドを使う方が簡単です。

3. for var in fileコマンドで完了

for var in fileは、変数varがファイル内をループしていることを意味します。値の区切りは$IFSによって決定されます。

for line in $(cat data.dat)
do
 echo "File:${line}"
done

for line in `cat data.dat`
do
 echo "File:${line}"
done

入力テキストの各行にスペースがない場合、改行区切りで入力テキストをループします。

入力テキストにスペースまたはタブが含まれる場合は、改行ではなく、lineはスペースセパレータまたはタブまたは改行で入力テキストをループします。

IFSに改行を設定することで、行単位で読み取ることができます。

IFSのデフォルト値は空白(含む:スペース、タブ、改行)です。

概要

シェルスクリプトでテキストファイルを一行ずつ処理する方法についての説明は以上となります。Shellでテキストファイルを処理する方法については、BinaryDevelopの過去の記事を検索するか、以下の関連記事を引き続き参照してください。