ファイル名のリストがあり、パスを取得できるようにコマンドを見つけるためにファイルを1つずつ提供したいと思います。 forループを使用し、catコマンドを使用して変数のすべてのファイル名を取得し、変数を1つずつfindコマンドに渡しましたが、機能しません。誰でも私を案内できますか?
for f in $(cat filelist.txt)
do
find /home/abc/ -type f -name "$f"
done;
エラーは発生しませんが、出力も取得できず、出力を変数に入れようとしましたが、運がありません。
答え1
各行に保存されているファイルの1つの名前を持つファイルを見つけるには、sをfilelist.txt
使用する簡単な方法があります。zsh
globbing
names=( ${(f)"$(<filelist.txt)"} ) &&
(( $#names )) &&
print -rC1 -- /home/abc/**/${(~j[|])names}(D.)
あなたのアプローチがうまくいかない理由は何の問題もありませんが、すぐには明確ではありません。
- では、
bash
引用されていないコンテンツペア(zshでのみ分割)$(cat filelist.txt)
のコンテンツに対してSplit + globを呼び出しますfilelist.txt
。デフォルト$IFS
(分割セクションの場合)を使用すると、改行だけでなくスペースやタブでも分割されます。したがって、その中に行がある場合は、呼び出されたファイルではなく、呼び出されたファイルと呼び出されたファイルをmy file.txt
探します。my
file.txt
my file.txt
- file
*
というファイルがある場合filelist.txt
全体的な状況セクションは、スクリプトが呼び出されるディレクトリのファイルのリストに展開されます。 -name '*'
名前付きファイルも検索されませんが、*
渡されたコンテンツは-name
パターンとして処理されるため、すべてのファイルが報告されます。ワイルドカード演算子を無効にするには、エスケープ[
とwithが?
必要です。*
\
\
今、あなたの質問は次のとおりです。
filelist.txt
LF の代わりに CRLF 区切り文字を使用する MSDOS テキスト形式です。これを実行してdos2unix
問題を解決します。- ファイルパス
filelist.txt
(たとえばdir/file.txt
)があります。-name
ファイル名のみが一致するため、絶対一致しません。
ここではループの代わりにGNUを使用できますxargs
。
xargs -rd'\n' -a filelist.txt -I NAME find /home/abc/ -name NAME -type f
ただし、これはまだ各ファイル名全体を把握することを意味し、/home/abc/
これは非効率的です。
代わりに、次のようにすることができます。
xargs -rd'\n' -n200 -a <(sed 's/[*?\\[]/\\&/g' filelist.txt) sh -c '
for name do
set -- -o -name "$name"
shift
done
shift
find /home/abc/ \( "$@" \) -type f' sh
find /home/abc/ \( -name name1 -o -name name2... \) -type f
1回の呼び出しで最大200の名前を呼び出すことができます。find
つまり/home/abc
、 1 つだけ呼び出すほど良くはありませんがはるかにzsh
良いです。
sed
また、名前にはエスケープされたワイルドカード文字を使用します。そこも通れますdos2unix
。
答え2
また試み
find -iname $(sed -z 's/\n$//; s/\n/ -o -iname /g' list.txt)
*nix テキスト・ファイルにあってはならない文字sed -z
で終わる行を探し、\000
ファイル全体をメモリーにロードします。その後、末尾の<NL>
文字を削除して残りの文字に置き換えることで、edファイル名の長いリストを取得できます-o -iname
。find
or