特定のディレクトリ内のすべてのファイル(ただし、事前定義されたリストのファイルのリスト)に対していくつかのタスクを実行する使い捨てユーティリティを作成する必要があります。与えられたリストはあらかじめ定義されているので、それを配列にハードコーディングします。
それでは、与えられた配列にないすべてのファイルの名前をどのように取得できますか?これは標準のUnixスクリプト(bash、awk、Perl)です。
答え1
これにより、bash
次のことができます。
all=(*)
except=(file1 file2 notme.txt)
only=()
IFS=/
for file in "${all[@]}"; do
case "/${except[*]}/" in
(*"/$file/"*) ;; # do nothing (exclude)
(*) only+=("$file") # add to the array
esac
done
ls -ld -- "${only[@]}"
(これは現在のディレクトリのファイルに対して機能しますが、検索のために配列要素を連結するためにall=(*/*) except=(foo/bar)
使用するなどのグローバル変数には信頼できません/
。)
"${array[*]}"
これは、配列の要素が(ファイルには表示されないため、$IFS
ここで選択した最初の文字)に関連付けられているという事実に基づいています。/
名前; NULはファイルに現れない文字です。道しかし、残念ながらbash
(逆にzsh
変数にそのような文字を持つことはできません)。したがって、その中の各ファイルについて$all
(ここでは$file
存在をfoo
例として使用)除外するかcase "/file1/file2/notme.txt/" in (*"/foo/"*)
どうかを確認します。$file
答え2
以下を使用する方が簡単ですzsh
。
except=(file1 file2 notme.txt)
all=(*)
only=(${all:|except})
ls -ld -- $only
ニーモニック${all:|except}
:要素$all
バーそれら$except
。
$except
ファイルが次のように配列にあることを確認することもできます。グローバル予選:
ls -ld -- *.txt(^e:'((except[(Ie)$REPLY]))':)
または、次の機能を使用してください。
in_except() ((except[(Ie)${1-$REPLY}]))
ls -ld -- *.txt(^+in_except)
答え3
ファイル名が十分に単純な場合は、次のものを使用できます。バッシュGLOBIGNORE
変数:
シェル
GLOBIGNORE
変数を使用して、パターンに一致するファイル名のセットを制限できます。GLOBIGNORE
設定されている場合、GLOBIGNORE
これらのパターンのいずれかに一致する各一致ファイル名が一致リストから削除されます。このオプションを設定すると、大文字と小文字に関係なく、nocaseglob
inのパターンに一致するものが検索されます。GLOBIGNORE
設定されていて空でない場合、filename.
と..
は常に無視されます。GLOBIGNORE
ただし、GLOBIGNORE
null以外の値に設定すると、dotglob
シェルオプションを有効にする効果があるため、 ''で始まる他のすべてのファイル名が.
一致します。 「」で始まるファイル名を無視する以前の動作を取得するには、.
「.*
」を設定します。このオプションはGLOBIGNORE
設定されていないとdotglob
無効になります。GLOBIGNORE
$ echo *
bin boot dev etc home lib lib64 lost+found mnt opt proc root run sbin srv sys tmp usr var
$ except=(etc lib lib64 tmp sbin)
$ GLOBIGNORE=$(IFS=:; printf "%s" "${except[*]}")
$ echo *
bin boot dev home lost+found mnt opt proc root run srv sys usr var
もちろん、配列を作成する場合は、変数を直接設定できますGLOBIGNORE
。
GLOBIGNORE=etc:lib:lib64:tmp:sbin
リストにある適切なbashワイルドカードパターンを利用することもできます。
GLOBIGNORE=etc:lib*:tmp:sbin