web-dev-qa-db-ja.com

〜(バックアップファイル)で終わるファイルのリストを避ける

私の要件は、~(バックアップファイル)で終わるファイルを除いて、ディレクトリ内のすべてのファイルをリストすることです。

私はコマンドを使用しようとしました:

ls -l | grep -v ~    

私はこの出力を取得します:

asdasad
asdasad~
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell1.sh~
testshell2.sh
testshell2.sh~
testtwo.txt
testtwo.txt~
test.txt
test.txt~

これらのファイルのみを取得したい:

asdasad
file_names.txt
normaltest.txt
target_filename
testshell1.sh
testshell2.sh
testtwo.txt
test.txt
20
curious_one
ls -l | grep -v ~

これが機能しない理由は、チルドがホームディレクトリに展開されるため、grepがリテラルのチルドを決して見ないためです。 (例: チルダ展開に関するBashのマニュアル を参照してください。)展開を防ぐには、引用符で囲む必要があります。

ls -l | grep -v "~"

もちろん、これにより、ファイル名の途中やlsの出力のどこかにさえ、チルダのある出力行は削除されます(ユーザー名や日付などには表示されない可能性があります)。ティルダで終わるファイルのみを本当に無視したい場合は、

ls -l | grep -v "~$"
49
ilkkachu

GNU lsの実装(ほとんどのLinuxシステムにあります)には、そのためのオプションがあります:-Bバックアップを無視:

ls --ignore-backups
49
hschou

Bashを使用している場合は、extglobが有効になっていることを確認してください。

_shopt -s extglob
_

それからあなたは使うことができます:

_ls -d -- !(*~)
_
  • _-d_ディレクトリの内容を表示しない
  • !(*~) _~_で終わるファイルを除くすべてのファイル

Zshでは、kshglobオプションを使用するか、独自の拡張グロブを使用して同じことを実行できます。

_setopt extended_glob
ls -d -- ^*~
_

除外するサフィックスは1文字だけなので、最後の文字がチルダではないファイル名と一致させることもできます(これはextglobなしでも機能するはずです)。

_ls -d -- *[^~]
_

ただし、一般的な考え方は_ls --ignore-backups_を使用することです。

24
Ravexina

これは役立つはずです:

ls -l | grep -v '~'  

理由:〜文字は、コマンドが実行される前にホームディレクトリに置き換えられます。試す

echo ~

そして

echo '~'
12
Nico Mittenzwey

他の返信で述べたように、問題が発生する可能性が高いのは、チルドを引用またはエスケープしなかったためです。

特定の使用例の1つとして、シェルファイル名の拡張を使用して同様のことを行いました。私は2003年頃から使用しています。つまり、さまざまな種類のシステム上で非常に多種多様なシェル実装に取り​​組んできました。 (ここでも-Cソートされた列に素敵な表示が欲しいからです)

ls -C *[!~]

(シェルのファイル名拡張を使用する場合の制限は、もちろん、非常に多数の(非バックアップ)ファイルがあるディレクトリでは、拡張が使用可能な引数リストのサイズを超えるためですが、最近のほとんどのシステムでは、この制限があります。かなり高い、多くの場合250KB以上、時にはそれ以上)

6
Greg A. Woods

正しい答えはたくさんありますが(特に@Foonが好きです)、ls -lで名前のリストを取得するのは、さまざまな理由でやや不十分です。

ファイルを見つけるための適切なツールは、当然のことながら、findです。

その結果の1つは、「選択ロジック」を単独で処理できることです。たとえば、次のようになります。

$ find . -maxdepth 1 \( -type f -a \! -name '*~' \) -print

これは文字通りfindを次のように言います:

  1. 現在のディレクトリでファイルを探します:.
  2. それらをそのディレクトリのレベルでのみ検索します。つまり、再帰しないでください:-maxdepth 1
  3. そこで、エンティティを探します。

    • タイプファイル:-type f
    • および:-a
    • 名前が~で終わっていないもの:! -name *~!は、ファイル名-name *~に一致する次のディレクティブを否定します)。

    (タイプと名前の完全一致を論理ユニットとして表示するには、()で括弧で囲みます)。

  4. 見つかった各ファイルの名前を出力します:-print

シェルに特殊な一部の文字がシェルによって解釈されないように保護する必要があります。そのため、括弧とバング!がバックスラッシュでエスケープされ、名前パターン*~、単一引用符で囲まれています。

findコマンドは、そのオプションの使用を通じて非常に強力なミニ言語を備えています。たとえば、ファイルシステムツリー全体(またはツリー)を再帰的に処理し、スキャン中に特定のディレクトリを省略するように指示される場合があります。ファイルのいくつかの属性(作成時間、変更時間、サイズなど)を照合することができます。

1
kostix

ls | grep -v '~$'はクイックソリューションです。 lsを使用してすべての(非表示ではない)ファイルを一覧表示し、次に-v(逆一致、つまり除外)を指定したgrepを使用して、末尾にチルダ(~)があるすべての行を除外します($)。

しかし、something1、something2のような名前のファイルがある場合、それは、ワークフローが悪いことを示す巨大な臭いのインジケーターであり、lsの動作を変更するような不格好なハックではなく、ソースで修正する必要があります。

Test1とtest2またはtestoneとtesttwoのようなバージョン番号を使用してファイルに名前を付けている場合、本当に必要なのはgitのようなバージョン管理システムです。

これは、複数のファイルの複数のバージョンがあり、すべてのファイル間でバージョン管理を調整する必要がある場合に特に当てはまります。

バージョン管理システムを使用すると、基本的にファイルシステムに時間枠をオーバーレイできるため、1つのtestファイルのみが表示されますが、内部では(バージョン管理プログラムを通じて)すべてのバージョンを検索、取得、元に戻すことができます。と、比較するなど.

これを設定すると、バージョン管理にファイルの履歴が残っているため、それ以降、1,000回の変更を行った場合でも、エディタからのバックアップファイルは必要ありません。履歴のタイムラインを「分岐」させ、新しいアイデアを試し、必要に応じて時間を遡って別のアイデアを試すこともできます。

1