yuu_nkjm blog
2009-11-27(Fri) 編集
[Linux][command][sed][grep] grepとsedで文字列の一括置換
grepとsedを使って,特定のディレクトリ以下のファイルに含まれる文字列を一括置換したい.そこで,以下の手続きを実行するコマンドを発行する.
「秀丸のGrepして置換」の機能を想定した.findしてgrepしてxarg sedの方が汎用性高そうだったな.
- 特定のディレクトリ以下のファイルで,置換したい文字列を含むファイルのリストを生成する.
- 置換を実行したくないファイル名が含む文字列を指定することで,置換の対象としないファイルを取り除き,置換を実行すべきファイルのリストを生成する.
- 置換を実行したいファイルにおいて,置換を実行する.
簡単に言うと
grep -Erl '置換したい文字列' | \
grep -v "置換したくないファイル名" | \
xargs sed -i バックアップファイルのサッフィクス 's/置換したい文字列/置換後の文字列/g'
くどく説明すると
grep -Erl 'sedによる置換を適用したいファイルの中身に含まれる文字列' | \
grep -v "置換したくないファイル名が含む文字列" | \
xargs sed -i バックアップファイルのサッフィクス 's/置換したい文字列/置換後の文字列/g'
コマンドライン
最後の"-i"をつけると,バックアップファイルが作成されファイルが上書き編集される.
grep -Erl '置換したい文字列' | \
grep -v "置換したくないファイル名" | \
xargs -n 1 -i "バックアップファイルのサッフィクス" sed '1s/^/---------------{}--------------\n/' {} | \
sed 's/置換したい文字列/置換後の文字列/g'|lv
関連資料
- grep
-E, --extended-regexp PATTERNを拡張された正規表現として扱います。 -e PATTERN, --regexp=PATTERN PATTERNをパターンとして指定します-で始まるパターンを保護するために有効です。 -r, --recursive 各ディレクトリ下のすべてのファイルを再帰的に読み取ります。これは -d recurse オプションと等価です。 -l, --files-with-matches 通常の出力はせず、このオプションを指定しなかったときに出力される入力ファイルの名前を表示します。スキャン動作は最初のマッチで終了します。 -v, --invert-match 結果を反転し、マッチしなかった行を選択します。
grepのman
- sed
-i[SUFFIX], --in-place[=SUFFIX] edit files in place (makes backup if extension supplied) g G Copy/append hold space to pattern space. s/regexp/replacement/ パターンスペースに対してregexpのマッチを試みる。マッチに成功すると、マッチした部分をreplacementに置換する。replacementは特殊文字である&を含むことができ、これはパターンスペースのマッチした部分を参照する。また\1から\9までの特殊エスケープを含むこともでき、これはregexpの副表現(sub-expression)にマッチした部分をそれぞれ参照する。
sedのman
sedで使用できる正規表現演算子
POSIX 1003.2で規定されているsedでは、以下の演算子が使用できます。
- .
- *
- ^
- $
- \(regexp\)
- \1 \2 \3 \4 \5 \6 \7 \8 \9
- [char-list]
- \{n,m\}
- \{n,\}
- \{n\}
- [:alnum:]
- [:alpha:]
- [:blank:]
- [:cntrl:]
- [:digit:]
- [:graph:]
- [:lower:]
- [:print:]
- [:punct:]
- [:space:]
- [:upper:]
- [:xdigit:]
GNU sedでは上記のものに加えて、以下のものが使えます。
付記: GNU sed 4.0.5ではオプション指定によりEREを使えるようになります(使えるEREはGNU のegrepと同じ)。
GNU sed 4.1.2 ではオプション指定によりPerl5互換の正規表現を使えるように なります(有効にしてコンパイルした場合)。また、正規表現演算子として\sと\Sが使えるようになっています。正規表現メモより
2012-11-27(Tue) 編集
[Linux][openSUSE][lsof] ポートやファイルの利用状況を調べる(ファイルをオープンしているプロセスを調べる)
lsof
ポートの利用状況を調べたい時,ファイルをどのプロセスがオープンしているのかを調べたい時などは,lsofコマンドを使う.
- そのポートは既に誰かがバインディングしてるから使えへんで!
- 外付けHDD上のファイルを誰かがオープンしているから,umountできへんで!
とか怒られたときに有用.
あるポートを使用しているプロセスを表示
lsof -i:80,8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 2655 tomcat 48u IPv4 2185755 0t0 TCP *:http-alt (LISTEN) httpd2-pr 9079 root 3u IPv4 2731119 0t0 TCP *:http (LISTEN)
あるプロセスが使用しているファイルを表示
lsof -c tomcat COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME tomcat-sy 2633 tomcat cwd DIR 252,0 4096 2 /
あるユーザが使用しているファイルを表示
lsof -u root|lv COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME systemd 1 root cwd DIR 252,0 4096 2 / systemd 1 root rtd DIR 252,0 4096 2 /
あるファイルを使用しているプロセスを表示
lsof /mnt/exthdd COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME bash 30959 root cwd DIR 8,49 4096 2 /mnt/exthdd lsof 30988 root cwd DIR 8,49 4096 2 /mnt/exthdd lsof 30989 root cwd DIR 8,49 4096 2 /mnt/exthdd