web-dev-qa-db-ja.com

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

異なるフォルダに同じ名前のファイルがたくさんあります。すべてのパスを見つけてテキストファイルに書き込むにはどうすればよいですか?

3
aortizma

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

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[]は、このファイル名の出現回数をカウントするハッシュ(nでキーが付けられたもの)であり、p[]は(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
3
roaima

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に保存されます

2
maulinglawns

インストールされている場合は、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は、ハードドライブの1日1回のスキャンでデータベース検索を実行するため、findよりもはるか高速です。
  • 今日追加したファイルは見つかりません。
  • 特定のパスまたはファイルシステムとマウント内のファイルは検出されません(cat /etc/updatedb.confを実行して、除外されているものを確認してください)。
1
pLumo

これは、複数回出現するすべてのファイル名を検索する完全なスクリプト(私はfind-double-names.shと呼びます)です。クリーンアップする場合は、同じ名前のファイルの内容が異なる可能性があることに注意してください。

例えば。ホームディレクトリ内のすべての二重ファイル名を見つけるには、次のように実行します。

find-double-names.sh $HOME

検索に含めるディレクトリをさらに渡すことができます。例:

find-double-names.sh $HOME /usr/local /var/tmp

多くのファイルがある場合、このスクリプトの実行には時間がかかることがあり、/ tmpにディスク容量が必要になる場合もあります。

#!/bin/bash

# This is the name of this script itself.
#
script="${0##*/}"

# The  arguments passed to this script are the parent
# directories to be searched, e.g: /home/me /usr/local
# Check if any given. If not, error out.
#
if [ -z "$1" ] ; then
    echo "Usage: $script <directory> [<directory>][...]" >&2
    exit 1
fi

# Create a temporary directory. For accurate results we need
# to be sure it is empty. This is one way to do this: create
# an temp dir that is garanteed to not exist yet.
#
# If you want to keep the "outputdir" with the results, make sure
# output dir you use does not contain files you want to keep, because
# files will be removed from it by this script! Better yet, make
# sure it is empty before starting this script.
#
outputdir=$(mktemp --tmpdir -d "${script}.XXXXXXXXXX")   # ensures new unique directory
trap "rm -r $outputdir" INT HUP QUIT ABRT ALRM TERM EXIT # ensures it is deleted when script ends

# Search the directories given as arguments, and process
# the paths of alle files one by one in a loop.
#
find "$@" -type f | while read path ; do
    filename="${path##*/}"
    echo "$path" >>"${outputdir}/${filename}.txt"
done

# Finally, if you want to end up with only file names that
# occur more than once, delete all output files that contain
# only one line.
#
for outputfile in $outputdir/*.txt ; do
    linecount=$(wc -l "$outputfile" | sed 's/ .*//')  # count lines in it
    if  [ "$linecount" = "1" ] ; then                 # if only one line
        rm "$outputfile"                              # remove the file
    fi
done

# Print the final result
#
for outputfile in $outputdir/*.txt ; do
    cat "$outputfile"
    echo               # empty line to separate groups of same file names
done
0
Hkoof

次の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にあり、そのsomefileはディレクトリabにあります。

0
Kusalananda