私の作業ディレクトリに一連のマークダウンファイルがあります。
$ 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
ただし、構造化されたコマンドはコマンドラインでは便利ではありません。より短いコマンドでこれらのタスクを実行するにはどうすればよいですか?
答え1
否定一致を使用する(必須ですが既に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
防止Next サブディレクトリ.md
)は()で終わり、()ファイルを-name '*.md'
含みません。!
today.md
'*.md'
シェルが実行される前に、現在のディレクトリの.mdファイルのリストに展開しようとしないように単一引用符を含める必要がありますfind
。
削除するファイルのリストが印刷されます。代わりに-print
削除してください-delete
。
答え3
上記の方法はより良い解決策ですが、コードが機能しない理由は比較によるものです。
「./today.md」は「today.md」と同じではありません。
答え4
Unixは、同じ単純なタスクを実行するさまざまな方法を提供することで有名です。一部の人は使用するのが好きですsed
が、私は好むので、grep
コマンドラインに入力すると次のようになります。
rm -i `ls *.md | grep -v '^today.md$'`
ls *.md
を含むすべての名前をリストします.md
。|
結果はls
次のコマンドにパイプしますが、副作用のためにls
ファイルは1行に1つずつ複数行にリストされます。grep -v '^today.md$'
正確に一致しないエコラインtoday.md
rm -i
その後、結果が得られたら(コマンドがバックティック内にあるため)、1つずつ削除するかどうかを尋ねます。私は生成されたファイルのリストを使用するときにジェネレータに問題が発生した場合に備えて、常にこれを行います。をrm
使用することなくファイルを削除できますが、-i
これはより危険で、削除されたファイルのリストを提供しません。