*/*/*/*/ ... */*.h または .hpp で書かれたいくつかのファイルがあります。ファイル自体ではなく、これらのファイルのディレクトリをインポートする必要があります。 sedを使用して「最後/行を見つけて\ nまで次のエントリを削除する」などの操作を実行する方法はありますか?
PS:\(. * \)または(. *)がi番目の発生\ iを呼び出すことを知っていますが、sedに\ iを削除するように指示する方法はありますか? \
編集:
次の操作を実行してファイルを生成しました。
find . | grep *.h >> file ; find . | grep *.hpp >> file
私が処理したいのはこのファイルの内容です。
答え1
ファイル名のサフィックスを含むファイルを含むディレクトリをインポートするか、.h
次.hpp
を使用しますfind
。
find . -type f \( -name '*.h' -o -name '*.hpp' \) -exec dirname {} \;
これは、指定された2つのパターンのうちの1つに一致するすべての一般ファイルのパス名を探します。これらの各パス名に対して、このdirname
ユーティリティはパス名のディレクトリパス部分を抽出するために使用されます。
GNUを使用するとfind
これを行うことができます
find . -type f \( -name '*.h' -o -name '*.hpp' \) -printf '%h\n'
これは非標準フォーマットオプションを使用して、パス-printf
名(つまりディレクトリパス)の「ヘッダー」を印刷します%h
。
一意のパス名を取得するには、ファイルの代わりにディレクトリ検索に切り替えることができます。
find . -type d -exec bash -O nullglob -O dotglob -c '
for pathname do
set -- "$pathname"/*.{h,hpp}
[[ $# -ne 0 ]] && printf "%s\n" "$pathname"
done' bash {} +
これはbash
、ディレクトリのバッチパス名の短いスクリプトを実行します。短いスクリプトはnullglob
、シェルオプションが有効な状態で実行されますdotglob
。これは、一致しないワイルドカードパターンが削除され、ワイルドカードパターンが隠された名前と一致する可能性があることを意味します。
このループは現在のパス名の配置を繰り返し、各ディレクトリ内の2つのワイルドカードパターンの合計を拡張します*.h
。*.hpp
パターンが 1 つ以上の名前と一致すると、ディレクトリのパス名が出力されます。
ただし、最後のバリアントは、通常のファイルだけでなく、*.h
名前または一致するすべての種類のファイルを含むディレクトリを報告します。*.hpp
zsh
シェルから:
typeset -U dirs=(./**/*.(h|hpp)(.ND:h))
print -r -C1 $dirs
dirs
これにより、一意の要素のみを格納する配列変数が生成されます。これを*.h
一致する一般ファイルを含む現在のディレクトリの下のディレクトリセットに初期化する*.hpp
か、配列の内容を印刷します。