マジックモードでファイルを探す

マジックモードでファイルを探す

/etc/magic と /usr/share/misc/magic の一致パターンに基づいて出力ファイルのコンテンツタイプを定義する bash コマンドファイル (1) があります。

「find」コマンドのテストでこれらのパターンを使用して「魔法」ファイルを定義する方法はありますか?

たとえば、テキストファイルと「PalmOSアプリケーション」ファイルがあります。

file -b palmapp
PalmOS application

file -b readme.txt
ASCII text

「ASCIIテキスト」の代わりに「PalmOSアプリケーション」と一致するファイルを見つけるには、いくつかの方法が必要です。たとえば、次は理想的なコマンドです。

find . -magic "PalmOS*"

このテストのために各ファイルに対して1行のbashコマンドを書く方法についてのアイデアはありますか?

答え1

おおよそ次のようになります。

find . -print -exec file {} \; | grep "PalmOS"

awkを介して出力をパイプするには、次を追加します。

| awk '{print substr($1,2,length($1)-2)}'

答え2

findファイルの内容を分析するための組み込み機能はありませんが、fileシェルを使用して複数のタスク固有のプログラムを組み合わせること(findディレクトリツリーのナビゲーション、fileファイルの内容の分析)はUnixの方法で作業を実行します。

file -b -- "$filename"コマンドの出力に文字列を含むファイルに対して操作を実行しようとしていますPalmOS application。シェルスクリプトでテストできます。

case "$(file -b -- "$filename")" in *"PalmOS application"*) true;; *) false;; esac

findこのスクリプトは、次のコマンドで使用できます。

find . -type f -exec sh -c 'case "$(file -b "$0")" in *"PalmOS application"*) true;; *) false;; esac' {} \; -print

-printやりたいことに置き換えてください(他のものかもしれません-exec …)。 2番目のジョブは、前のジョブがtrueの場合にのみ実行されます(つまり、シェルコマンドは0(true)を返します)。

あるいは、zsh で以下を使用して、シェルにディレクトリー・ナビゲーションを実行させることもできます。**全体的な状況。これ. グローバル予選一般ファイル(たとえば)の一致を制限-type fしますfind

for x in **/*(.); do
  [[ $(file -b -- $x) = *"PalmOS application"* ]] || continue
done

Bash ≥4.3では再帰ワイルドカードを使用できますが、最初にそのオプションを有効にする必要があり**ます。globstarBash 4.0〜4.2ではglobstarすでに利用可能ですが、**ディレクトリシンボリックリンクを閲覧するときは注意してください。set -o globstarksh93ではshopt -s globstar

shopt -s globstar
for x in **/*; do
  [[ -f $x ]] || continue
  [[ $(file -b -- "$x") = *"PalmOS application"* ]] || continue
done

ファイル名にスペースやスペースが含まれていない場合、:\"'別のアプローチはファイル名に対して実行して出力をfile解析することです。

find -type f |
xargs file |
sed -n 's/:.*PalmOS application.*//p' |
xargs somecommand

ファイル名にスペースが含まれているが改行やコロンがない場合は、シェルを使用して解析できます。

find -type f |
while IFS=: read -r filename type; do
  case "$type" in
    *"PalmOS application"*)
      …;;
  esac
done

答え3

これは使用しませんが、質問が要求する結果をfind設定しpatternて生成します。directory

pattern="PalmOS application"
directory=.

for f in $directory/*; do
    if [[ $(file -b $f) == "$pattern" ]]; then
        echo $f; 
    fi; 
done

関連情報