シェルスクリプトを介して実行したいプロジェクトがあります。
私は約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
文字列を含むディレクトリを見つけます。ただし、find
30年前のすべての日付に対してディレクトリツリー全体で作業を実行するには時間がかかります*。
だから私は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
したり、望むものではありませんbar
。baz
files
あなたが望むもの:
grep 'foo
bar
baz' files
代わりに。これを行うには、次の手順を実行します。
IFS=$'\n'
grep -- "${a[*]}" files
構文を使用すると、最初の文字$IFS
は配列の要素を連結するために使用されます"${a[*]}"
。これは配列をサポートするすべてのシェルで動作します(ksh
、、、、(その部分はまだ機能していませんが、リテラル改行文字を使用する必要があります))。zsh
bash
yash
$'\n'
yash
を使用すると、zsh
次の操作も実行できます。
grep -e$^a files
これは次のように拡張されます。
grep -efoo -ebar -ebaz files
これは別の文字列を検索する別の方法です。
(配列に一致させる正規表現の代わりに検索する固定文字列が含まれている場合は、このオプションを使用する必要があります-F
。)