sedとはstream editorの略称で、中国語では「ストリームエディタ」と呼ばれます。
sedコマンドはライン指向の処理ツールであり、「ライン」を処理単位として1行ごとに処理を行い、処理結果は標準出力(STDOUT)に出力されます。sed コマンドは非常に丁寧なコマンドであることがわかり、読み取ったファイルにむやみに変更を加えず、内容を標準出力に出力します。
sed のコマンド形式を見てみましょう。
sedコマンドファイル
- コマンド部分: 各行の内容に対して実行される処理 (この部分は非常に重要です)。
- file 部分: 処理対象のファイル file パラメータを省略した場合、sed は標準入力を処理対象として使用します。
sedはどのように機能しますか?
先ほど述べたように、sed コマンドは「行」指向であり、コンテンツを一度に 1 行ずつ処理します。処理中、sed は処理対象の行をバッファに格納し、sed コマンドを使用してバッファの内容を処理し、処理が完了するとバッファの内容が画面に送信されます。次に、次の行を処理し、ファイルの終わりまで繰り返します。このバッファを「パターン空間」と呼びます。
前述したように、このプロセス中、sed コマンドはファイル自体に変更を加えません。
誰もが感覚的に理解できるように、sed コマンドの最も単純な例を見てみましょう。
#まず元のファイルの内容を見てみましょう [roc@roclinux ~]$ cat roc.txt test 1 test2 testtest XtestX BBtest #sed コマンドを使用して、ファイル内の文字「2」を含む行を削除したいと考えています。ファイル [roc@roclinux ~] $ sed '/2/d' roc.txt test 1 testtest XtestX BBtest
この例では、sed を使用して、roc.txt ファイル内の文字「2」を含む行を削除します。ご覧のとおり、この例は非常に単純です。このコマンドのコマンド部分は であり/2/d
、一重引用符で囲まれています。また、これを行う方法、sed の使用方法を学習する必要があります。また、コマンド部分を一重引用符で囲むことを忘れないでください。/2/d
d の d は削除を意味します。これは、特定の行の内容に文字 2 が含まれている限り、その行が削除されることを意味します。(sed によるいわゆる削除はすべてパターン空間で実行され、実際には元の roc.txt ファイルは変更されません。)
sedコマンドを使用してcutコマンドの効果を実現したい
Cut-d:-f 1/etc/passwd と同様の効果、つまりコロンを区切り文字として使用して最初のドメインを抽出したい場合、sed コマンドをどのように使用すればよいでしょうか?
#まず /etc/passwd ファイルの内容を見てみましょう [roc@roclinux ~]$ head -n 5 /etc/passwd root:x:0:0:root:/root:/bin/bash bin: x:1 :1:bin:/bin:/sbin/nologin デーモン:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/ nologin lp: x:4:7:lp:/var/spool/lpd:/sbin/nologin #今回は sed コマンドを使用して、ファイル内の各行の最初のフィールドを抽出します。区切り文字はコロン [roc@roclinux]です。 ~]$ head -n 5 /etc/passwd|sed 's/:.*$//' root bin デーモン adm lp
ご覧のとおり、コマンド 部分 を指定しました's/:.*$//'
。これは、最初のコロンより前の内容が残るように、最初のコロンから各行の終わりまでの部分をクリアする必要があることを意味します。
sed の便利なオプションは何ですか?
sed コマンドのオプションについては、-n
そのオプションについて言及する必要がありますが、このオプションを明確に説明するには、やはりある程度の頭脳と文章が必要です。
前述したように、sed はパターン空間内の行を処理して標準出力に出力します。これがデフォルトの処理方法です。つまり、この行を「d」で削除しない限り、「パターンスペース」で処理された行はすべて標準出力(画面)に出力されてしまいます。次の例を見てみましょう。
#最初に元のファイルの内容を見てみましょう [roc@roclinux ~]$ cat roc.txt 1 2 3 4 5 #よく見てください、出力には 2 つの「4」があります [roc@roclinux ~]$ sed '/4 /p' roc.txt 1 2 3 4 4 5
元のファイルの内容がすべて出力され、文字 4 を含む行が 2 回出力されます。
ただし、これが sed コマンドの仕組みであり、最初に処理された行を出力してから、後続のアクションを実行します。(ここでは p を設定します。これは、この行を出力することを意味します。) これは明らかに本来の意図を満たしていませんが、sed コマンドで 4 を含む行を見つけて出力するだけです。
この際、-n
オプションを追加して試してみると、希望どおりの結果が得られることがわかります。
[roc@roclinux ~]$ sed -n '/4/p' roc.txt 4
-n
このオプションは、sed コマンドに対して、「出力することが明確に示されている行でない限り、ランダムな出力を与えないでください」と厳しく警告します。-n
このオプションは、一致する行を出力することを意味する p と組み合わせて使用されることがよくあります。
コマンド部分には色々な工夫がされています
前に紹介したことを思い出してください。sed コマンドのコマンド形式は次のとおりです。
$ sedコマンドファイル
このうち、コマンド部分は sed コマンドの本質であり、コマンド部分を使いこなせるかどうかで sed マスターになれるかどうかが決まります。
コマンド部分は範囲設定とアクション処理の2つの知識に分けることができます。
スコープは 2 つの異なる方法で表現できます。
- 行数を指定します。たとえば、「3,5」は 3、4、5 行目を意味し、「5,$」は 5 行目からファイルの最終行までを意味します。
- パターン マッチング: たとえば、/^[^dD]/ は、d または D で始まらない行をマッチングすることを意味します。
アクション処理部分では、選択できる幅広いアクションが提供されます。最も一般的に使用されるアクションのいくつかを次に示します。
- d:行の削除を示します。
- p: この行を出力します。
- r: 指定されたファイルの内容を読み込みます。
- w: 指定されたファイルに書き込みます。
- a: 以下に新しい行と新しいコンテンツを挿入します。
sed の力を見せつける時が来た
事実は言葉よりも雄弁です。4 つの例を使用して、sed コマンドが本当に「強力な」プレーヤーであることを誰もが感じられるようにするつもりです。
最初の例では、テスト ファイルの 10 行目から 20 行目の内容を表示してみましょう。
#先ほどの行範囲を指定する方法を採用しました [roc@roclinux ~]$ sed -n '10,20p' test
2 番目の例では、d または D で始まるすべての行内のすべての小文字の x 文字を大文字の X 文字に変更しようとします。
[roc@roclinux ~]$ sed '/^[dD]/s/x/X/g' テスト
この使用法については議論する価値があります。コマンド部分で /AA/s/BB/CC/g の構文形式を使用します。これは、ファイル内の AA を含む行と一致し、これらの行のすべての BB を CC に置き換えることを意味します。 。
3 番目の例では、各行の最後の 2 文字を削除します。
#ドットは 1 つの文字を表し、2 つのドットは 2 つの単一文字を表します [roc@roclinux ~]$ sed 's/..$//' test
「なぜ sed'/..$/d'test を使用できないのですか? d は削除の意味ではないのですか?」と疑問に思う人もいるかもしれません。d は文字ではなく行の内容全体を削除することを意味するため、d を使用することはできません。'/..$/d'
これは、すべての行を末尾の 2 文字と一致させてから、その行全体を削除することを意味しますが、これは明らかに本来の意図に反しています。
4 番目の例では、各行の最初の 2 文字を削除します。
[roc@roclinux ~]$ sed の/..//' テスト
これら 4 つの例を通して、sed コマンドの最も一般的な使用法を誰もが直感的に理解できたと思いますので、この知識を実際の作業に活用してください。
& 記号の驚くべき使用法
この知識ポイントについても、シナリオを通じて説明します。
#いつものように、ファイルの内容が最初に表示されます [roc@roclinux ~]$ cat mysed.txt 北京 ロンドン #& 記号を使用しました。その機能を推測してみてください [roc@roclinux ~]$ sed 's/B .*/&2008/' mysed.txt 北京2008 ロンドン
このコマンドの機能は、「B.*」を含む文字列の末尾に 4 文字 2008 を追加することです。このコマンドでは & 文字を使用します。sed コマンドでは、これは「以前に一致した部分」を表し、この例ではもちろん北京です。
アンパサンドについての全員の理解を強化するために、別の例を使用してみましょう。
#この例の方が理解しやすいかもしれません [roc@roclinux 20160229]$ sed 's/Bei/&2008/' mysed.txt Bei2008jing London
sed のかっこには深い意味があります
sed コマンドでは、括弧「()」にも深い意味があります。早速本題に入り、例を通して括弧の威力を見てみましょう。
[roc@roclinux ~]$ echo "hello world" | sed 's/\(hello\).*/world \1/' 世界こんにちは
元々は「hello world」でしたが、sed 処理後の出力は「world hello」になっていることがわかります。
この例では、「sed の事前ストレージ技術」と呼ばれる括弧の知識を使用しています。つまり、コマンド内の「(」と「)」で囲まれた内容が一時的に順番に \1 、\2 に保存されます。 …内部。このようにして、「\N」フォームを使用して、これらの事前保存されたコンテンツを呼び出すことができます。
引き続き例を見てみましょう。各行の最初と最後の北京の後にのみ 2008 という文字列を追加したいと考えています。これは、各行の最初と最後の 2008 に加えて、この行の真ん中の文字列も追加することを意味します。行 「Beijing」が表示される場合は、その後に 2008 を追加しないでください。この要件は非常に複雑で個別化されていますが、sed コマンドはそれでも十分に満たすことができます。
#まずファイルの内容を見てください。最初の行には 4 つの北京があります [roc@roclinux ~]$ cat mysed.txt 北京 北京 北京 ロンドン ロンドン ロンドン #効果は得られますが、コマンドは非常に複雑です [roc@ roclinux ~]$ sed 's/\(北京\)\(.*\)\(北京\)/\12008\2\32008/' mysed.txt 北京2008 北京 北京2008 ロンドン ロンドン ロンドン ロンドン
このコマンドは確かに十分に複雑で、一般的な言葉で言えば「十分にサディスティック」です。この例では、プレストレージ テクノロジを再度使用して、最初の北京、中間のコンテンツ、最後の北京を表す 3 つのコンテンツを保存しました。\1
sumの場合\3
、その後に文字列 2008 を追加します。
行範囲のよりスマートなターゲティング
知識を学ぶには練習が一番です。この例を読めば、行範囲をより適切に配置する方法が理解できると思います。
#ファイルの内容を表示 [roc@roclinux ~]$ cat mysed.txt 北京 2003 北京 2004 北京 2005 北京 2006 北京 2007 北京 2008 北京 2007 # 2005 と 2007 に一致する行間の内容を表示したい [roc@ roclinux ~] $ sed -n '/2005/,/2007/p' mysed.txt 北京 2005 北京 2006 北京 2007
行範囲の最初の行と一致させるには /2005/ を使用し、行範囲の最後の行と一致させるには /2008/ を使用します。最後の行を照合するとき、要件を満たす最初の行に遭遇する限り、停止し、逆方向の照合は続行されないことがわかります。したがって、sed コマンドは最初の 2007 のみと一致し、2 番目の 2007 とは一致しませんでした。
-e オプションを使用して複数のコマンドを設定します
コマンド部分を思い出してください。ここで良いニュースがあります。つまり、sed コマンドには複数のコマンドを含めることができます。複数のコマンドを含める場合は、各コマンドの前に -e オプションを追加するだけです。
#2 つの -e オプションを使用して 2 つのコマンドを設定します [roc@roclinux ~]$ sed -n -e '1,2p' -e '4p' mysed.txt 北京 2003 北京 2004 北京 2006
注意すべき点が 1 つあります。それは、-e
コマンドの内容の直後にオプションを指定する必要があり、他のオプションは許可されないということです。-e
オプションは複数のコマンドの設定をサポートしています。これは本来良いことであり、いくつかの置換効果をより便利に実現できるようになります。しかし、これは嬉しい悩みでもあり、コマンドをたくさん設定した場合、その実行順序はどうなるのか?
これを理解していないと、-e
オプションは利便性ではなく混乱をもたらす可能性があります。次の例を見てみましょう。
#まずファイルの内容を確認します [roc@roclinux ~]$ cat mysed.txt 北京 2003 北京 2004 北京 2005 北京 2006 北京 2007 北京 2008 #2 つのコマンドを設定します [roc@roclinux ~]$ sed -e 's /北京/ロンドン/g' -e '/北京/d'mysed.txt ロンドン 2003 ロンドン 2004 ロンドン 2005 ロンドン 2006 ロンドン 2007 ロンドン 2008
前者のコマンドは北京をロンドンに置き換えることを意味し、後者のコマンドは北京の文字列を含む行を削除することを意味しますが、最終的な結果はすべての行が出力され、削除された行は見つかりません。これは、最初のコマンドが北京をロンドンに置き換えたため、2 番目のコマンドは北京を見つけることができないためです。
上の例のコマンドの位置を逆にして、その効果を見てみましょう。
#最初に削除アクションを指定し、次に置換アクションを指定します [roc@roclinux 20160229]$ sed -e '/Beijing/d' -e 's/Beijing/London/g' mysed.txt [roc@roclinux 20160229] $
これら 2 つの小さな例を通して、複数のコマンドがコマンド内の順序に従って実行されることが明確にわかります。
-fオプションを使用してコマンドファイルを設定します
sed コマンドのコマンド部分が非常に長い場合は、内容を別のファイルに書き込み、オプションを使用して-f
このファイルを sed コマンドのコマンド部分として指定できます。
#これは事前に作成したファイルです [roc@roclinux ~]$ cat called /2004/,/2006/p # -f オプションを使用してコマンド ファイルを指定します [roc@roclinux ~]$ sed -n -f mysed .txt と呼ばれる 北京 2004 北京 2005 北京 2006
理解するのは簡単です。-f
オプションは難しくなく、頻繁に使用します。よく使用される一致ルールの一部を別のファイルに保存するので、それらを覚えることを心配する必要はありません。
コンテンツの挿入
sed コマンドはあなたが思っているよりもはるかに強力で、この行の内容を処理するだけでなく、この行の後に内容を挿入することもできます。
#挿入する内容を別のファイルに保存します [roc@roclinux ~]$ cat ins.txt ====China==== #処理したいファイルを表示 [roc@roclinux ~]$ cat mysed .txt 北京 2003 北京 2004 北京 2005 北京 2006 北京 2007 北京 2008 #見てください、r を使用して挿入を実装します [roc@roclinux ~]$ sed '/2005/r ins.txt' mysed.txt 北京 2003 北京 2004 北京 2005 = ===中国==== 北京2006 北京2007 北京2008
効果からわかるように、ins.txt ファイルの内容を、ファイル内の 2005 文字列を含む行の下の行に挿入しました。
ファイルを指定して挿入するだけでなく、a\ を使用して特定の行の「下」に特定のコンテンツを挿入することもできます。
#ファイルの内容 [roc@roclinux ~]$ cat new.txt 北京 2004 北京 2005 北京 2006 # 2004 の次の行に中国を挿入したいと考えています [roc@roclinux ~]$ sed '/2004/a\China' mysed。 txt 北京 2003 北京 2004 中国 北京 2005 北京 2006 北京 2007 北京 2008
ご覧のとおり、a\
挿入するコンテンツを使用して追加するだけで、これを簡単に実現できます。
学生の中には、コンテンツは行の下に挿入できるのに、行の上にコンテンツを挿入できるのかと疑問に思う人もいるかもしれません。もちろん、答えはi\
アクションを使用することです。
[roc@roclinux ~]$ sed '/2004/i\China' mysed.txt 北京 2003 中国 北京 2004 北京 2005 北京 2006 北京 2007 北京 2008
あなたの行動について話してください
y アクションを紹介する前に、まずそれによってどのような効果が得られるかを見てみましょう。
#元のファイル内容 [roc@roclinux ~]$ cat mysed.txt 北京 2003 北京 2004 北京 2005 北京 2006 北京 2007 北京 2008 #y は文字順で前後を置き換える [roc@roclinux 20160229]$ sed 'y/ei /ie/' mysed.txt ビージェン 2003 ビージェン 2004 ビージェン 2005 ビージェン 2006 ビージェン 2007 ビージェン 2008
この例は実際には非常に明確で、すべての e と i を交換したいと考えています。学生の中には、との違いは何ですかと
尋ねる人もいます。ポイントは主に次の2つです。y///
s///
- y の構文形式は y/source/dest/ です。これは、source の文字を dest の文字で置き換えることを意味します。s の構文形式は s/regexp/replacement/ で、正規表現に一致した内容が置換部分に置き換えられることを意味します。
- y は、多くのトリックを必要とせず、単純な単語ごとの置換です。s は、& シンボルやプリストレージなどの機能をサポートしており、より柔軟な置換効果を実現できます。
このとき、一部の GEEK は、y/ee/ei/ がどのような影響を与えるかという状況を思い浮かべるかもしれません。ここには同じ文字が 2 つあるため、例を通して見てみましょう。
[roc@roclinux 20160229]$ sed 'y/ee/ie/' mysed.txt 北京 2003 北京 2004 北京 2005 北京 2006 北京 2007 北京 2008
ご覧のとおり、ソース部分に繰り返し文字がある場合、最初に出現したビット置換のみが影響し、後続のビット置換は影響を受けません。おそらく、次の例がより明確になるでしょう。
#元のファイルの内容 [roc@roclinux ~]$ cat mysed.txt 北京 2003 北京 2004 北京 2005 北京 2006 北京 2007 北京 2008 #iji から iba への置換では、j から b のみが効果を持ちます [roc@roclinux 20160229]$ sed 'y/iji/iba/' mysed.txt 北氷 2003 北氷 2004 北氷 2005 北氷 2006 北氷 2007 北氷 2008
n 個のアクションを通じて行の下方向への移動を制御します
場合によっては、偶数番号のラインを特定の置換を行うだけで済むなど、インターレース処理の効果を実現したい場合がありますが、このときは n アクションの助けが必要です。
#原文件内容 [roc@roclinux ~]$ cat mysed.txt Beijing 2003 Beijing 2004 Beijing 2005 Beijing 2006 Beijing 2007 Beijing 2008 #我们同时使用了n动作和y动作 [roc@roclinux ~]$ sed ‘/200/{n;y/eijng/EIJNG/;}’ mysed.txt Beijing 2003 BEIJING 2004 Beijing 2005 BEIJING 2006 Beijing 2007 BEIJING 2008
大文字の BEIJING が 1 行おきに表示されていることがわかります。これが、このn
オプションの動作方法です。その実際の機能は、現在の行が置換アクションを回避できるように、コンテンツの次の行を処理キャッシュに入れることです。これは、左キーと右キーを使用して置換アクションを回避するのと似ていませんか?子供の頃にゲームをするときにBOSS? 大きな動きです、笑。
指定された行を特定のファイルに書き込みます
記事はもう終わりに近づいています。最後に、非常に実用的なアクションである w アクションを説明しましょう。このアクションは、一致したコンテンツを別のファイルに書き込み、コンテンツをフィルタリングして保存するために使用できます。
#2004、2005、2006 を含む行を new.txt ファイルに保存 [roc@roclinux ~]$ sed '/200[4-6]/w new.txt' mysed.txt 北京 2003 北京 2004 北京 2005 北京 2006 北京 2007 北京 2008 #私たちが望むコンテンツがボウルに到着しました [roc@roclinux ~]$ cat new.txt 北京 2004 北京 2005 北京 2006