同じ名前のすべてのファイルを探す

同じ名前のすべてのファイルを探す

別のフォルダに同じ名前のファイルがたくさんあります。すべてのパスを見つけてテキストファイルに書き込むには?

答え1

これは重複したファイル名があることを知っていますが、それが何であるかわからない一般的なケースを処理します。

find -type f -print0 |
    awk -F/ 'BEGIN { RS="\0" } { n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'

awkスクリプトはNULLで終わるファイルパスを処理し(したがって改行文字を含むことができるファイル名を処理できます)、それを$0現在のファイルパス名にします。この変数はnファイル名部分を保持します。このファイル名の発生回数を計算するハッシュk[](キーとも呼ばれる)であり、最初の対応するフルパス名を保持する別のハッシュ(キーとも見なされる)です。np[]n

はい

# Preparation
mkdir -p tmp/a tmp/b
touch tmp/a/xx tmp/a/yy tmp/b/yy tmp/b/zz

# Do it
find tmp -type f -print0 |
    awk -F/ 'BEGIN { RS="\0" } { n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'

tmp/a/yy
tmp/b/yy

# Tidyup
rm -rf tmp

POSIXを使用している場合find(Macを使用している場合など)、対応するオプションがないため、-print0回避策とコマンドが若干異なります。明示的な起動ディレクトリを指定する必要があります。また、このバージョンはfindNULLで終わるファイル名を処理しないため、改行文字を含まないファイル名でのみ機能します。

find . -type f -print |
    awk -F/ '{ n=$NF } k[n]==1 { print p[n]; } k[n] { print $0 } { p[n]=$0; k[n]++ }'

答え2

私は次のように使用しますfind

find <path> -type f -name <filename> > same_name.txt

例:

find . -type f -name "foo" > same_name.txt
cat same_name.txt 
./dir_a/foo
./foo
./dir_b/foo
./tmp/foo

上記のコードは現在のディレクトリから始まり、名前付きのすべてのファイルを再帰的に検索しますfoo。結果はファイルに保存されますsame_name.txt

答え3

インストールすると使用できますlocate

locate filename

またはファイルに保存:

locate filename > same_name.txt

特定の場所のみを検索するには、grepを使用して結果をフィルタリングできます。

locate filename | grep "/path/"
# e.g. search only in your /home folder
locate filename | grep "$HOME"

メモ:

  • locateはいたくさんfindデータベース検索を実行するために1日に1回ハードドライブを検索するので、速度が速くなります。
  • 今日追加したファイルは見つかりません。
  • 特定のパス、ファイルシステム、およびインストールでファイルを検索しません。 (cat /etc/updatedb.conf除外されたアイテムを表示するには実行してください。)

答え4

次のbashスクリプトは、スクリプトのコマンドラインで指定された最上位パス(またはパスが指定されていない場合は現在のディレクトリ)で、一般ファイル(または一般ファイルへのシンボリックリンク)と重複するすべての名前を繰り返し探します。

:最後に、対応するファイル名を見つけることができる区切られたディレクトリ名のリストとともに、各重複ファイル名の要約が提供されます。

#!/bin/bash

shopt -s globstar  # enable the ** glob
shopt -s dotglob   # also let patterns match hidden files

declare -A dirs    # where we store directories for each found name

for pathname in "${1:-.}"/**; do
    [ ! -f "$pathname" ] && continue  # not something we're interested in

    name=${pathname##*/}
    if [ -n "${dirs[$name]}" ]; then
        # we have seen this filename before
        dups+=( "$name" )
    fi

    # append directory name to ':'-delimited list for this filename
    dirs[$name]=${dirs[$name]:+"${dirs[$name]}:"}"${pathname%/*}"
done

# go through the list of duplicates and 
# print the found directory names for each
for name in "${dups[@]}"; do
    printf '%s:\n\t%s\n' "$name" "${dirs[$name]}"
done

例を実行してください:

$ bash script.sh
somefile:
        ./a:./b
.profile:
        .:./t

要約は、.profile現在のディレクトリとディレクトリで見つかり、tディレクトリsomefileaで見つかったことを示しますb

関連情報