find
他のコマンドの出力に基づいて複数のファイルを処理しようとするシナリオがあります。
コマンド自体は
./libopt -d test . 2>&1 | sed -rn 's/Cannot find library \"(.*?)\"/\1/p'
これは私に次のような結果を与えます
libopcodes-2.25-system.so
libbfd-2.25-system.so
libz.so.1
libdl.so.2
libc.so.6
libosal.so
libarchive.so.13
libcrypto.so.1.0.0
libfreetype.so.6
libpng12.so.0
libpthread.so.0
libts-1.0.so.0
libgcc_s.so.1
libssl.so.1.0.0
libm.so.6
ld-linux.so.3
libxml2.so.2
libbz2.so.1.0
liblzma.so.5
liblzo2.so.2
libattr.so.1
libacl.so.1
libnettle.so.4
とにかく、各ファイルの場所を見つけるために、この入力を次のfindコマンドに提供できますか?
find /usr -name <INPUT_LINE>
答え1
問題のある文字(たとえば、内の文字)がライブラリ名に存在しないとし、IFS
リストを繰り返して、各文字を新しいクエリに渡します。
./libopt -d test . 2>&1 | sed -rn 's/Cannot find library \"(.*?)\"/\1/p' \
| while read libname; do
find /usr -name "$libname"
done
それ以外の場合は、単一ファイルシステムの配信(上記は各入力ファイルに対して1つずつ実行)の場合、このfind -name
オプションはファイル名リストの一致には適していないため、単一のファイルシステム検索の出力がに渡される可能性がありますgrep
。/usr
検索範囲を絞り込むというディレクトリだけを探していますlib
。
./libopt -d test . 2>&1 | sed -rn 's/Cannot find library \"(.*?)\"/\1/p' > blah
find /usr/lib /usr/*/lib -type f | grep -F -f blah
mktemp
問題がある場合は、blah
生成されたファイル名を使用してください。高度なシェルを使用すると、grep
プロセス置換形式でスキーマファイルを動的に生成できます。
答え2
ファイル名を単一の正規表現に変換するか(大文字と小文字を区別しない)オプションを使用できますfind
。-regex
-iregex
libs=$(./libopt -d test . 2>&1 |
sed -rn 's/Cannot find library \"(.*?)\"/\1/p' |
xargs -r | sed -e 's/ /|/g ; s/\./\\./g')
[ -n "$libs" ] && find /usr -regextype egrep -iregex ".*/($libs)"
xargs
すべてのファイル名をスペースで区切って1行に入力します。次のコマンドはsed
スペースを|
and に変更します。このコマンドは、$ libsが空でない場合にのみ実行されます。.
\.
find
注:出力するファイル名が多すぎると(数千)、コマンドは./libopt
2xargs
行以上を出力し、$ libsが大きすぎて1つのコマンドラインに収まらず中断されます。これが可能であれば(出力結果を考慮するとそうではありません)、次のようにループでandを./libopt
実行してxargs | sed
問題を解決できます。find
libs=$(./libopt -d test . 2>&1 | sed -rn 's/Cannot find library \"(.*?)\"/\1/p')
for re in $(echo "$libs" | xargs | sed -e 's/ /|/g ; s/\./\\./g') ; do
find . -regextype egrep -iregex ".*/($re)"
done
答え3
そしてzsh
:
files=(
${(f)"$(./libopt -d test . 2>&1 |
sed -rn 's/Cannot find library \"(.*?)\"/\1/p')"})
glob=('$files['{1..$#files}']')
eval "paths=(**/(${(j:|:)glob})(D.))"
ls -ld -- $paths
同様の質問に対する答えを確認してください。https://unix.stackexchange.com/a/265815説明が必要な場合やない場合は、いくつかの選択肢を確認してくださいzsh
。