ファイルから配列をgrepし、検索パターンを再利用します。

ファイルから配列をgrepし、検索パターンを再利用します。

シェルスクリプトを介して実行したいプロジェクトがあります。

私は約30年間持続してきた長期間の毎週のラジオ番組カタログを持っています。ソースが異なるため、名前の形式もかなり異なる場合があります。これにより、私が持っているショーと欠けているショーが何であるかを知ることは困難です。

標準の日付形式でシンボリックリンクを作成し、ファイル名を実際の表示ディレクトリ(ある場合)への日付シンボリックリンクとして使用したいと思います。

たとえば、私が言いたいことは

'2015-09-25' -> '../Radio Show/2015-09-25 Special Guest/'
'2015-10-02' -> '../Radio Show/Very funny! 2015-10-02 Show'

日付形式も多様ですが、今はYY-MM-DD、YYYY-MM-DD形式を探すのが悩みだけです。

だから私は以下を使用して各行がから1980-01-01の日付であるファイルを作成しました。2010-12-31この回答

次に各行を読み取り、それを使用して名前に対応するfind文字列を含むディレクトリを見つけます。ただし、find30年前のすべての日付に対してディレクトリツリー全体で作業を実行するには時間がかかります*。

だから私はfind -type d . > filesystem.txtすべてのディレクトリ名を含むファイルを作りました。その後、grep各日付文字列に対してディスク上で実行するのではなく、そのファイルの各日付文字列に対して実行できますfind

ただし、日付ファイルの各行をgrepにロードするのに問題があります。

Butを使用すると、$ grep -f dates.txt filesystem.txt 次の形式ですべての結果を取得できます。

./complete/1996-02-18
./complete/1996-03-03
./complete/1996-03-31
...

文字列パラメータを使用して結果を取得する方法がわかりません。

'1996-03-31' -> './complete/1996-03-31'

私はこれを試しましたが、$ grep "${dates[@]}" metadata/filesystem.txt期待どおりに動作しません。

grep: 1988-01-03: No such file or directory
grep: 1988-01-04: No such file or directory

私がやりたいことの擬似コードのバージョンは次のとおりです。

foreach ( date-string in dates.txt ) {
  grep date-string in filesystem.txt
  if (match) {
     ln -s match date-string
  }
}

Bashでどうすればいいですか?

-*すべての日付を使用しないことでこれを簡素化できますが、ラジオ番組がすべての記録で同じ日に行われるかどうかはわかりません。日付を見逃していないことを確認したいので、30年の範囲内のすべての日付を使用したいと思います。

ベストアンサー1

トピックの質問に答えてください。grepを使って配列内の要素を見つける方法

a=(foo bar baz)
grep "${a[@]}" files

する:

grep foo bar baz files

つまり、検索fooしたり、望むものではありませんbarbazfiles

あなたが望むもの:

grep 'foo
bar
baz' files

代わりに。これを行うには、次の手順を実行します。

IFS=$'\n'
grep -- "${a[*]}" files

構文を使用すると、最初の文字$IFSは配列の要素を連結するために使用されます"${a[*]}"。これは配列をサポートするすべてのシェルで動作します(ksh、、、、(その部分はまだ機能していませんが、リテラル改行文字を使用する必要があります))。zshbashyash$'\n'yash

を使用すると、zsh次の操作も実行できます。

grep -e$^a files

これは次のように拡張されます。

grep -efoo -ebar -ebaz files

これは別の文字列を検索する別の方法です。

(配列に一致させる正規表現の代わりに検索する固定文字列が含まれている場合は、このオプションを使用する必要があります-F。)

おすすめ記事