find
そこで、との組み合わせを使用して、grep
プレーン テキスト ドキュメントからファイル名のリストをフィルター処理します。
実行するコマンドは次のとおりです。
find /Volumes/Documents\ -\ Part\ 1/July 2009 -type f | grep -vf files.txt
files.txt には次の内容があります:
/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages
一致しない行を出力したいのですが、代わりに次のようになります:
grep: invalid character range
原因は何でしょうか? files.txt には他にもたくさんの内容がありますが、長すぎるため省略しました。そこにはいくつかの Unicode 文字も含まれています。それが問題の原因となっているのでしょうか?
Mac OS X Yosemite、bash 3.2.57(1)-リリース、grep (BSD grep) 2.5.1-FreeBSD
答え1
TLDR;追加-F
grepのオプション-f
は、リストを含むファイルを参照するために使用されます。パターン- ファイルにはパターンのリストは含まれず、ファイル名のリストが含まれています
男のgrep
-f FILE、--file=FILE FILE から 1 行に 1 つずつパターンを取得します。空のファイルにはパターンが含まれないため、何にも一致しません。(-f は POSIX で指定されています。)
ファイル名内のメタ文字をメタ文字として扱いたくない場合は、そのメタ文字がエスケープされていることを確認する必要があります。
$ cat files.txt
/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages
$ echo a | grep -vf files.txt
a
あなたの files.txt には、おそらく表示されている 4 行以上の行が含まれていると思われます。
ファイルを確認するには
$ wc files.txt
4 21 221 files.txt
$ sum files.txt
43924 1
疑わしい場合は、-F
オプション (大文字の F) を使用します。ただし、その場合、file.txt 内のメタ文字はエスケープされません。
以下の点に注意してください
$ cat files.txt
/Volumes/Documents - Part 1/July 2009/vacation.pdf
/Volumes/Documents - Part 1/July 2009/pie time!.jpg
/Volumes/Documents - Part 1/July 2009/Coding/Unix/sample.sh
/Volumes/Documents - Part 1/July 2009/trip-to-spain.pages
[z-a]
$ echo aaa | grep -vf files.txt
grep: Invalid range end
$ echo aaa | grep -Fvf files.txt
aaa
この-F
オプションは、検索パターンに正規表現が含まれていないこと、および検索パターンをプレーンテキストとして扱う必要があることを grep に伝えます。