私の要件は、~
(バックアップファイル)で終わるファイルを除いて、ディレクトリ内のすべてのファイルをリストすることです。
私はコマンドを使用しようとしました:
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
ls -l | grep -v ~
これが機能しない理由は、チルドがホームディレクトリに展開されるため、grep
がリテラルのチルドを決して見ないためです。 (例: チルダ展開に関するBashのマニュアル を参照してください。)展開を防ぐには、引用符で囲む必要があります。
ls -l | grep -v "~"
もちろん、これにより、ファイル名の途中やls
の出力のどこかにさえ、チルダのある出力行は削除されます(ユーザー名や日付などには表示されない可能性があります)。ティルダで終わるファイルのみを本当に無視したい場合は、
ls -l | grep -v "~$"
GNU ls
の実装(ほとんどのLinuxシステムにあります)には、そのためのオプションがあります:-B
バックアップを無視:
ls --ignore-backups
Bashを使用している場合は、extglob
が有効になっていることを確認してください。
_shopt -s extglob
_
それからあなたは使うことができます:
_ls -d -- !(*~)
_
-d
_ディレクトリの内容を表示しない!(*~)
_~
_で終わるファイルを除くすべてのファイルZshでは、kshglob
オプションを使用するか、独自の拡張グロブを使用して同じことを実行できます。
_setopt extended_glob
ls -d -- ^*~
_
除外するサフィックスは1文字だけなので、最後の文字がチルダではないファイル名と一致させることもできます(これはextglob
なしでも機能するはずです)。
_ls -d -- *[^~]
_
ただし、一般的な考え方は_ls --ignore-backups
_を使用することです。
これは役立つはずです:
ls -l | grep -v '~'
理由:〜文字は、コマンドが実行される前にホームディレクトリに置き換えられます。試す
echo ~
そして
echo '~'
他の返信で述べたように、問題が発生する可能性が高いのは、チルドを引用またはエスケープしなかったためです。
特定の使用例の1つとして、シェルファイル名の拡張を使用して同様のことを行いました。私は2003年頃から使用しています。つまり、さまざまな種類のシステム上で非常に多種多様なシェル実装に取り組んできました。 (ここでも-C
ソートされた列に素敵な表示が欲しいからです)
ls -C *[!~]
(シェルのファイル名拡張を使用する場合の制限は、もちろん、非常に多数の(非バックアップ)ファイルがあるディレクトリでは、拡張が使用可能な引数リストのサイズを超えるためですが、最近のほとんどのシステムでは、この制限があります。かなり高い、多くの場合250KB以上、時にはそれ以上)
正しい答えはたくさんありますが(特に@Foon
が好きです)、ls -l
で名前のリストを取得するのは、さまざまな理由でやや不十分です。
ファイルを見つけるための適切なツールは、当然のことながら、find
です。
その結果の1つは、「選択ロジック」を単独で処理できることです。たとえば、次のようになります。
$ find . -maxdepth 1 \( -type f -a \! -name '*~' \) -print
これは文字通りfind
を次のように言います:
.
-maxdepth 1
そこで、エンティティを探します。
-type f
-a
~
で終わっていないもの:! -name *~
(!
は、ファイル名-name *~
に一致する次のディレクティブを否定します)。(タイプと名前の完全一致を論理ユニットとして表示するには、(
と)
で括弧で囲みます)。
-print
。シェルに特殊な一部の文字がシェルによって解釈されないように保護する必要があります。そのため、括弧とバング!
がバックスラッシュでエスケープされ、名前パターン*~
、単一引用符で囲まれています。
find
コマンドは、そのオプションの使用を通じて非常に強力なミニ言語を備えています。たとえば、ファイルシステムツリー全体(またはツリー)を再帰的に処理し、スキャン中に特定のディレクトリを省略するように指示される場合があります。ファイルのいくつかの属性(作成時間、変更時間、サイズなど)を照合することができます。
ls | grep -v '~$'
はクイックソリューションです。 lsを使用してすべての(非表示ではない)ファイルを一覧表示し、次に-v
(逆一致、つまり除外)を指定したgrepを使用して、末尾にチルダ(~
)があるすべての行を除外します($
)。
しかし、something1、something2のような名前のファイルがある場合、それは、ワークフローが悪いことを示す巨大な臭いのインジケーターであり、lsの動作を変更するような不格好なハックではなく、ソースで修正する必要があります。
Test1とtest2またはtestoneとtesttwoのようなバージョン番号を使用してファイルに名前を付けている場合、本当に必要なのはgit
のようなバージョン管理システムです。
これは、複数のファイルの複数のバージョンがあり、すべてのファイル間でバージョン管理を調整する必要がある場合に特に当てはまります。
バージョン管理システムを使用すると、基本的にファイルシステムに時間枠をオーバーレイできるため、1つのtest
ファイルのみが表示されますが、内部では(バージョン管理プログラムを通じて)すべてのバージョンを検索、取得、元に戻すことができます。と、比較するなど.
これを設定すると、バージョン管理にファイルの履歴が残っているため、それ以降、1,000回の変更を行った場合でも、エディタからのバックアップファイルは必要ありません。履歴のタイムラインを「分岐」させ、新しいアイデアを試し、必要に応じて時間を遡って別のアイデアを試すこともできます。