システム・プログラム 電子・情報工学系 新城 靖 <yas@is.tsukuba.ac.jp>
このページは、次の URL にあります。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/syspro-2001/2001-06-25
あるいは、次のページから手繰っていくこともできます。
http://www.hlla.is.tsukuba.ac.jp/~yas/coins/
http://www.is.tsukuba.ac.jp/~yas/index-j.html
例:appleをorangeに変える。% sed -e '命令1' -e '命令2' -e '命令3' input > output![]()
% sed -e 's/apple/orange/' input > output![]()
<範囲>の指定方法
<コマンド><引数>
/
」以外も使える。「s:文字列1:文字列
2:
」でも、「s@文字列1@文字列2@
」でもよい。
文字列1(置き換えの元の文字列)で、「\(正規表現\)」は、文字列2(置き換え 先の文字列)では、「\1」、「\2」、「\3」で参照可能である。 数は、何番目の正規表現かを示す。 何度でも使ってもよい。
例:
---------------------------------------------------------------------- % ls c*.c | catcont-0.c cont-1.c cont-2.c % ls c*.c | sed 's/cont-\([0-9]\)/\1-continue/'
0-continue.c 1-continue.c 2-continue.c %
----------------------------------------------------------------------
---------------------------------------------------------------------- #!/bin/csh -f sed -e 'sed-com1' \ -e 'sed-com2' \ -e 'sed-com3' ... | \ shell-com1 | \ shell-com2 ----------------------------------------------------------------------csh では、行末キャンセルが必要になることが多い。
sh では、「''」の中に改行を含められる。 パイプの後の行末キャンセルも不要である。
---------------------------------------------------------------------- #!/bin/sh sed -e ' sed-com1 sed-com2 sed-com3 ' ... | shell-com1 | shell-com2 ----------------------------------------------------------------------コマンドラインやシェル・スクリプトの中で使う時には、 sed の命令を引用符「''」で括るとよい。 引用符「''」は、シェルによりはがされ、 sed コマンド本体には渡されない。
引用符「''」で括らなかった時には、「$」や「*」など が、シェルによって解釈され、sed には渡されない。
シェル・スクリプトで、引数やシェル変数を参照したい時には、 sed のコマンド全体を引用符「''」で 括り、その中で変数の部分だけ引用符を解除する。
---------------------------------------------------------------------- #!/bin/csh -f sed -e 's/aaa/'$1'/' ... ----------------------------------------------------------------------変数に空白が含まれている可能性がある時には、さらに変数を「""」で括る。
---------------------------------------------------------------------- #!/bin/csh -f sed -e 's/aaa/'"$1"'/' ... ----------------------------------------------------------------------「#!」を使う時には、-f を付ける。
---------------------------------------------------------------------- #!/bin/sed -f sed-com1 sed-com2 sed-com3 ----------------------------------------------------------------------コマンドの場所は、which コマンドで調べる。
例:ls -l の結果のうち、先頭が「-」で始まるものについて、ファイル名と 大きさだけを表示する。% awk 'program' input > output![]()
% ls -l | awk '/^-/{printf("%d %s\n",$5,$9);}'![]()
<パタン> { <コマンド> } <パタン> { <コマンド> } <パタン> { <コマンド> }
<パタン>の指定方法
<コマンド>で書けること。
---------------------------------------------------------------------- % awk 'BEGIN { print 1 + "2" ; }' /dev/null3 %
----------------------------------------------------------------------
例:合計
---------------------------------------------------------------------- % awk '{s+=$1 } END {print s}'1
2
3
^D 6 %
----------------------------------------------------------------------
フィールドの区切り文字は、-F: で変更できる。 パスワード・ファイルをアクセスする時には、-F: を使う。
---------------------------------------------------------------------- % ypcat passwd | awk -F: '$1=="yas" {print}'yas:EfFxLk3yV3Ovx:1231:40:Yasushi SHINJO,[os],5163,?:/home/lab2/OS/yas:/usr/bin/tcsh %
----------------------------------------------------------------------
= += -= *= /= %= || && ! > >= < <= == != + - / % ++ --C言語にはない演算子
if( cond ) { statement1; } else { statement1; } for( expression1; condition; expression2 ) { ... break ; ... continue ; } for( variable in array ) { } while( condition ) { ... break ; ... continue ; } next; 次の行へ exit; END パタンへ
---------------------------------------------------------------------- % awk 'BEGIN { a["apple"] = 10; a["orange"] = 20; } { print $1,a[$1];}'apple
apple 10 ^D %
----------------------------------------------------------------------
---------------------------------------------------------------------- #!/bin/csh -f awk '{ \ ... \ } ' ... | \ shell-com1 | \ shell-com2 ----------------------------------------------------------------------csh では、行末キャンセルが必要になることが多い。
sh では、「''」の中に改行を含められる。 パイプの後の行末キャンセルも不要である。
---------------------------------------------------------------------- #!/bin/sh awk ' { ... ... }' ... | shell-com1 | shell-com2 ----------------------------------------------------------------------コマンドラインやシェル・スクリプトの中で使う時には、 awk の命令を引用符「''」で括るとよい。 引用符「''」は、シェルによりはがされ、 awk コマンド本体には渡されない。
引用符「''」で括らなかった時には、「$」が シェルによって解釈され、awk には渡されない。
シェル・スクリプトで、引数やシェル変数を参照したい時には、 awk のコマンド全体を引用符「''」で 括り、その中で変数の部分だけ引用符を解除する。
---------------------------------------------------------------------- #!/bin/csh -f awk -e 'BEGIN{ x="'$1'"; } ... ' ... ----------------------------------------------------------------------「#!」を使う時には、-f を付ける。
---------------------------------------------------------------------- #!/usr/bin/awk -f BEGIN { ... } { ... } ----------------------------------------------------------------------コマンドの場所は、which コマンドで調べる。
% newer filenameヒント:ls -t で、最終更新時刻の順に表示する。 sed で、先頭から引数の現れる行まで表示する。![]()
% show-n-m 10 20 filenameこの課題では、sed、または、awkを使いなさい。 head コマンドと tail コマンドを使ってはいけない。![]()
ヒント:sed で、行の範囲の指定を使うか、awk で、行番号を保持している変 数 NR を見て判定する。
% mv *.c *.cc「''」で括っても、mv コマンドはそれを解釈すること はできない。![]()
% mv '*.c' '*.cc'このような目的を果すようなシェル・スクリプトを生成するシェル・スクリプ ト make-mv-command を作りなさい。![]()
% ls *.cこのような mv は、危険なので、一度命令をファイルに落として内容を確認し てから実行するとよい。echo-server-fork.c echo-server-select.c % make-mv-command *.c > run
% cat run
mv echo-server-fork.c echo-server-fork.cc mv echo-server-select.c echo-server-select.cc % sh run
% ls *.c
echo-server-fork.cc echo-server-select.cc %
![]()
ヒント:sed の正規表現の置き換え sed の 置き換え先での置き換え元の正規表現の参照 の機能を使って、ファイル名を作る。
% funcs file.cこの課題では、完璧を目指さなくてもよい。いくつかの仮定を 入れて、スクリプトを簡単にしなさい。たとえば、 関数は、1行に1つしか現れないと仮定してよい。close main open printf read write %
![]()
ヒント:sed で、「xxx()」のようなパタンを拾って出力する。1つの sed の コマンドで完了させるのではなくて、複数の sed のコマンドを使う。
重複を外すには、sort して uniq すればよい。
% kill-name echo-server%
![]()
なお、csh, tcsh, bash 等の内部コマンドでは、ジョブ・コントロールの機能 を使って、名前でジョブ(プロセスのグループ)を殺す機能がある。
ヒント:単語の数は、NFを数える。 バイト数は、length() を使う。
ヒント:連想配列を使う。
---------------------------------------------------------------------- % a-finger yasヒント:パスワード・ファイルは、ypcat passwd の出力を使う。Login name: yas In real life: Yasushi SHINJO Office: [os], x5163 Home phone: ? Directory: /home/lab2/OS/yas Shell: /usr/bin/tcsh %
----------------------------------------------------------------------
---------------------------------------------------------------------- % sno yas998765 yas Yasushi Shinjo %
----------------------------------------------------------------------
---------------------------------------------------------------------- % cat today.cヒント:awk の NR を使って行番号を付ける。 awk に与える前に、expand で、タブを展開するとよい。#define TODAY "Monday" main() { printf("Today is %s.\n",TODAY ); } % nprint today.c
1: #define TODAY "Monday" 2: main() 3: { 4: printf("Today is %s.\n",TODAY ); 5: } %
----------------------------------------------------------------------
ヒント:「数字:」というパタンの行について処理する。 sed で行の頭から何文字か削るか、 awk の substr() で取り出す。
電子メールの本文にある From: のような文字列は無視しなさい。 電子メールのヘッダと本文の区切りは、空行 /^$/ でわかる。
継続行に対応しなさい。たとえば、次のようになっていた場合、To: としては 3行表示する。
---------------------------------------------------------------------- To: who1@domain.com, who2@domain.com, who3@domain.com ----------------------------------------------------------------------行の先頭が空白かタブならば、継続行である。その時には、前に設定したヘッ ダを使う。