Memo/Linux/find

http://dexlab.net/pukiwiki/index.php?Memo%2FLinux%2Ffind
 

find


findの結果をgzファイルにする

gzipは出力ファイル名を指定できない。

  • 「gzip -c example.log > example.foo.gz」は可能だが、元ファイルが残る
  • example.log-YYYYMMDDhhmmss.gz のように任意の名前で圧縮する
    1. export DATETIME=$(date +%Y%m%d%H%M%S)
    2. find /var/log/ -type f -name '*.log' \
    3.   -exec mv {} {}-$DATETIME \; \
    4.   -exec gzip {}-$DATETIME \;

findの結果をtar.gzファイルにする

tarの引数としてコマンドラインをそのまま渡すと、ファイルが多い場合に失敗する。そのため標準入力として渡す。

  • 例:/var/log の指定ファイルだけをまとめる
    1. sudo bash -c "find /var/log/ -type f -mtime -1 -follow -regextype posix-egrep -regex '.+/(messages.*|yum.*|secure.*)' | tar -cvz -T - --null -f logs.$(hostname -s).$(date +%Y%m%d-%H%M%S).tar.gz"
  • /tmp/logsに展開
    1. mkdir /tmp/logs
    2. tar xvfz logs.web01.20150616-063248.tar.gz -C /tmp/logs

findで.svnを除外したディレクトリのパーミッションを変更する

  • ディレクトリで、パーミッションが777以外の、.svn, .CVS, .gitを除外し、特定の名前のパーミッションを777に変更する
    1. find . -type d ! -perm 777 \
    2. ! \( -path '*.svn*' -prune \) \
    3. ! \( -path '*.CVS*' -prune \) \
    4. ! \( -path '*.git*' -prune \) \
    5. \( -name 'tmp' -or -name 'temp' -or -name 'cache' -or -name 'template_c' -or -name 'log' -or -name 'logs' \) \
    6. -exec chmod 777 {} \;

findコマンドオプション

  • /var/www/ 直下のディレクトリのみ表示。mindepthが無いと親ディレクトリも表示される
    1. find /var/www/ -maxdepth 1 -mindepth 1 -type d
  • 最新のファイルを一つ取得
    1. ls -t $(find /tmp/ -type f -name "*.x86_64.rpm") | head -1
  • ファイル名だけを表示(GNU findのみ)
    1. find . -type f -printf '%f\n'
  • リンク切れのシンボリックリンクを探す。-followを付けると結果が異なる
    1. find . -xtype l
  • 古いファイルと空ディレクトリを削除。"/tmp/*" がポイント。"*"が無いと"/tmp/"まで列挙され、削除しようとする
    1. find /tmp/* -type f -mtime +5 -delete -o -empty -type d -delete
  • 1日以内に変更のあったログを探す
    1. sudo find /var/log/ -mtime -1 -type f -follow | sort
  • 正規表現。デフォルトではEmacsの正規表現でエスケープが多用される。他に「-regextype posix-egrep」等も指定でき、こちらの方がわかりやすい
    • -typeと併用する場合、-typeより前に書かないと警告が出る
    • -regex pattern パス全体とマッチ。大文字小文字を区別する
      1. # 拡張子が".log", ".bak", ".tmp", ".old" のファイルを検索
      2.  
      3. # emacs形式
      4. find . -regex ".*\.\(log\|bak\|tmp\|old\)$" -type f
      5.  
      6. # posix-egrep形式
      7. find . -regextype posix-egrep -regex ".*\.(log|bak|tmp|old)$" -type f
    • -iregex pattern パス全体とマッチ。大文字小文字を区別しない
  • /var/log/ 以下の"*.log"にマッチする 60分以内に変更があったファイルサイズの合計(MB)
    1. find /var/log/ -name "*.log" -mmin -60 -type f -printf "%s\n" |awk '{sum += $1; printf("\r%d",sum/1024/1024) }; END{print""};'
  • cronで毎日04:05に、/var/log/test 以下の昨日より前の"*.log"ファイルをgz圧縮、90日を経過した"gz"ファイルは削除
    1. 5 5 * * * ( LOG_DIR=/var/log/test; /usr/bin/find $LOG_DIR -follow -name "*.log" -type f -mtime +1 -exec /bin/gzip {} \; ; /usr/bin/find $LOG_DIR -follow -name "*.gz" -type f -mtime +90 -delete; )
  • 削除
    1. # 空のディレクトリを削除
    2. find . -empty -type d -delete
    3.  
    4. # ファイルの削除(-deleteオプションが無いバージョンもあるようだ)
    5. find . -name '*.log' -delete
    6.  
    7. # 一つずつファイルを削除
    8. find . -name '*.log' -exec rm {} \;
    9.  
    10. # 「+」オプション。xargsのように複数指定
    11. find . -name '*.log' -exec rm {} +
  • 日付の範囲指定。例:14日前〜7日前までのファイルを列挙
    1. touch -t `date "+%m%d0000" --date "14 day ago"` /tmp/_start
    2. touch -t `date "+%m%d0000" --date "7 day ago"` /tmp/_end
    3. find -newer /tmp/_start -not -newer /tmp/_end
  • -mtime で日、-mmin で分単位で指定できる
    1. find -mtime -1 1(24時間)前〜現在
    2. find -mtime -3 3(72時間)前〜現在
    3. find -mtime 3  3(72時間)前〜4(96時間)
    4. find -mtime +3 4(96時間)前〜過去
    5.  
    6. # テスト用ファイルを作成
    7. touch -t `date "+%m%d%H%M" --date "60 min ago"` 60_min_ago.log
    8. touch -t `date "+%m%d%H%M" --date "1 day ago"` 1_day_ago.log
    9. touch -t `date "+%m%d%H%M" --date "2 day ago"` 2_day_ago.log
    10.  
    11. # 70分以前のファイルを検索
    12. find . -name '*.log' -type f -mmin +70
    13. ./2_day_ago.log
    14. ./1_day_ago.log
    15.  
    16. # 1日以前のファイルを検索
    17. find . -name '*.log' -type f -mtime +1
    18. ./2_day_ago.log
  • シンボリックリンク以下も検索したい
    • 例:/var/log/ 以下の*.logファイルを探したいが、/home/user1/log にシンボリックリンクが張ってある場合
      1. ln -s /home/user1/log /var/log/user1
      2.  
      3. # 通常 /home/user1/log 以下は表示されない
      4. find /var/log/ -name "*.log"
      5.  
      6. # 表示される
      7. find /var/log/ -follow -name "*.log"
      8. # または
      9. find -L /var/log/ -name "*.log"
  • ファイルサイズを指定
    • -size ファイルサイズc
    • k:KB, c:Byte, 指定せず:ブロックサイズ
    • -size 0c :ゼロバイトのファイル
    • -size +1000k :1M B以上のファイル
    • -size -500c :500Byte以下のファイル
      1. find  /var/log -size +1000k -print
      2. find  /home -size 0c -print

find+xargs

  • 特定のprefixのサービスを再起動する。例:iptables, ip6tablesを再起動する
    1. find /etc/rc.d/init.d/ -name 'ip*' -exec basename {} \; | xargs -i sudo /sbin/service {} restart
  • findしてcpやmvしたい場合、xargs -iオプションで"{}"に引数が入る
    1. find . -name "*.tmp" | xargs -i cp {} /tmp/
  • 日本語ファイル名を含むとエラーになる
    1. find . -perm 544 | xargs chmod 644
  • find単体では自動的にクォートしてくれるようで動作する
    1. find . -perm 544 -exec chmod 644 {} \;

空のディレクトリを探す/削除する

  • 空のディレクトリを探す
    find . -type d -empty
  • 空のディレクトリを削除する
    find . -type d -empty -delete

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2017-11-09 (木) 16:46:20 (168d)