この記事は、進行中の Unix Sed Tips and Tricks シリーズの一部です。
以前の sed 記事では、sed の印刷、sed の削除、sed の代用、sed ファイルの書き込み、および sed の複数のコマンドについて学びました。
この記事では、いくつかの実用的な例を使用して、sed の「s」置換コマンドを使用したいくつかの興味深い回避策を確認しましょう。
I. Sed 置換区切り文字
以前の投稿で説明したように、@ % | などのさまざまな区切り記号を使用できます。; :sed 代替コマンド内。
以下で説明するすべての例で使用される path.txt ファイルを最初に作成しましょう。
$ cat path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin /usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin: /opt/omni/lbin:/opt/omni/sbin:/root/bin
例 1 – sed @ デリミタ:/opt/omni/lbin を /opt/tools/bin に置き換えます
「/」を含むパス名を置き換える場合、「/」の代わりに @ を区切り文字として使用できます。以下の sed の例では、入力ファイルの最後の行で、/opt/omni/lbin が /opt/tools/bin に変更されています。
$ sed 's@/opt/omni/lbin@/opt/tools/bin@g' path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin /usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin: /opt/tools/bin:/opt/omni/sbin:/root/bin
例 2 – sed / デリミタ:/opt/omni/lbin を /opt/tools/bin に置き換えます
パス名関連の置換で「/」を使用する必要がある場合は、以下に示すように、置換データで「/」をエスケープする必要があります。この sed の例では、区切り文字「/」が REGEXP および REPLACEMENT 部分でエスケープされています。
$ sed 's/\/opt\/omni\/lbin/\/opt\/tools\/bin/g' path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin /usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin: /opt/tools/bin:/opt/omni/sbin:/root/bin
II. Sed '&' 一致した文字列を取得
正規表現が一致する入力行の正確な部分は &で表され、置換部分で使用できます。
例 1 – sed と使用法:/usr/bin/ を /usr/bin/local に置き換えます
$ sed 's@/usr/bin@&/local@g' path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin/local:/usr/sas/bin /usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin/local:/opt/omni/bin: /opt/omni/lbin:/opt/omni/sbin:/root/bin
上記の例では、置換部分の「&」は、一致するパターンである /usr/bin に置き換えて、/local を追加します。したがって、出力では /usr/bin のすべての出現箇所が /usr/bin/local に置き換えられます
例 2 – sed &使用法:行全体に一致
&は、指定された REGEXP に一致するものを置き換えます。
$ sed 's@^.*$@<<<&>>>@g' path.txt <<</usr/kbos/bin:/usr/local/bin:/usr/jbin/:/usr/bin:/usr/sas/bin>>> <<</usr/local/sbin:/sbin:/bin/:/usr/sbin:/usr/bin:/opt/omni/bin:>>> <<</opt/omni/lbin:/opt/omni/sbin:/root/bin>>>
上記の例では、正規表現には行全体に一致する「^.*$」があります。置換部分 <<<&>>> は、行頭と行末にそれぞれ <<<と>>> を付けて行全体を書き込みます。
III. Sed でのグループ化と後方参照
グループ化は通常の正規表現のように sed で使用できます。グループは「\(」で開き、「\)」で閉じます。グループ化は後方参照と組み合わせて使用できます。
後方参照とは、グループ化によって選択された正規表現の一部を再利用することです。 sed の後方参照は、正規表現と、substitute コマンドの置換部分の両方で使用できます。
例 1:各行の最初のパスのみを取得する
$ sed 's/\(\/[^:]*\).*/\1/g' path.txt /usr/kbos/bin /usr/local/sbin /opt/omni/lbin
上記の例では、\(\/[^:]*\) は最初の :が来る前に使用可能なパスに一致します。 \1 は、最初に一致したグループを置き換えます。
例 2:マルチグループ化
ファイル path.txt で、ファイルの最後の行のフィールドの順序を変更します。
$ sed '$s@\([^:]*\):\([^:]*\):\([^:]*\)@\3:\2:\1@g' path.txt /usr/kbos/bin:/usr/local/bin:/usr/jbin:/usr/bin:/usr/sas/bin /usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/omni/bin: /root/bin:/opt/omni/sbin:/opt/omni/lbin
上記のコマンドの $ は、最終行のみで置換が行われるように指定しています。出力は、最終行のパス値の順序が逆になっていることを示しています。
例 3:/etc/passwd ファイル内のユーザー名のリストを取得する
この sed の例では、/etc/passwd ファイルの最初のフィールドのみが表示されます。
$sed 's/\([^:]*\).*/\1/' /etc/passwd root bin daemon adm lp sync shutdown
例 4:各単語の最初の文字を括弧で囲む
この sed の例は、括弧内のすべての単語の最初の文字を出力します。
$ echo "Welcome To The Geek Stuff" | sed 's/\(\b[A-Z]\)/\(\1\)/g' (W)elcome (T)o (T)he (G)eek (S)tuff
例 5:単純な数をまとめます。
数字のリストを持つ numbers というファイルを作成しましょう。以下の sed コマンドの例は、数千までの数を commify するために使用されます。
$ cat numbers 1234 12121 3434 123 $sed 's/\(^\|[^0-9.]\)\([0-9]\+\)\([0-9]\{3\}\)/\1\2,\3/g' numbers 1,234 12,121 3,434 123