別のフォルダに同じ名前のファイルがたくさんあります。すべてのパスを見つけてテキストファイルに書き込むには?
答え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[]
(キーとも呼ばれる)であり、最初の対応するフルパス名を保持する別のハッシュ(キーとも見なされる)です。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
POSIXを使用している場合find
(Macを使用している場合など)、対応するオプションがないため、-print0
回避策とコマンドが若干異なります。明示的な起動ディレクトリを指定する必要があります。また、このバージョンはfind
NULLで終わるファイル名を処理しないため、改行文字を含まないファイル名でのみ機能します。
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
ディレクトリsomefile
とa
で見つかったことを示しますb
。