作業ディレクトリに一連のマークダウンファイルがあります。
$ ls *.md
csv_reader.md egrep.md find.md found_pdfs.md osPathSep_help.md readme.md smtplib_help.md today.md
「today.md」以外を削除したい
#!/usr/local/bin/bash
for i in ./*.md ; do
if [[ $i != "today.md" ]]; then
echo $i
fi
done
実行して取得
$ bash bash/remove_files.sh
./csv_reader.md
./egrep.md
./find.md
./found_pdfs.md
./osPathSep_help.md
./readme.md
./smtplib_help.md
./today.md
それにもかかわらず、構造化されたコマンドはコマンドラインでは便利ではありません。短いコマンドでこのようなタスクを実行するにはどうすればよいでしょうか。
否定一致を使用します(shopt -s extglob
が必要ですが、すでに設定されている可能性があります):
rm !(today).md
(最初にls
の代わりにrm
を使用して結果を確認できます)。
extglob
にはたくさんの力があります。
rm !(yesterday|today).md
2つのファイルを節約したい場合。
find . -maxdepth 1 -name '*.md' ! -name today.md -type f -print
現在のディレクトリ(-type f
-または明示的にそこにディレクトリ名を置く)内のすべてのファイル(.
)を見つける必要があります(-maxdepth 1
は 以下のサブディレクトリ )を防ぎますファイル.md
を除く(-name '*.md'
)を除いて、!
(today.md
)で終わります。
シェルがfind
を実行する前に現在のディレクトリの.mdファイルのリストに展開しないように、'*.md'
を一重引用符で囲んでください。
削除するファイルのリストを出力します。代わりに-print
を-delete
に変更して削除してください。
上記はより良い解決策ですが、コードが機能しない理由は比較のためです。
「./today.md」は「today.md」と等しくありません。
bashの拡張グロビング機能 を使用して、必要なファイルを除外したい場合の方が短い場合があります。
shopt -s extglob
echo rm -- !(today).md
上記(テストのためにecho
を削除した後)は、today
の後に.md
が続くものを除くすべてに一致すると述べています。
あなたの例はデフォルトではドットファイルと一致しませんでした。必要に応じて、shopt dotglob
でその動作を変更できます
使用したglobパターンが(適切に)ファイル名の前に./
を付けたため、スクリプトは記述どおりに機能しませんでした。したがって、内部テストは./today.md
と比較する必要があります。