.tsvファイルでいっぱいのディレクトリがあり、それらのそれぞれに対してgrepコマンドを実行して、テキスト行の特定のグループを引き出し、それを同様のファイル名で関連するテキストファイルに保存します。たとえば、ファイルの1つだけをgrepする場合、grepコマンドは次のようになります。
grep -h 8-K 2008-QTR1.tsv > 2008Q1.txt
しかし、私は次のようなtsvファイルのリストを持っています:
2008-QTR1.tsv
2008-QTR2.tsv
2008-QTR3.tsv
2008-QTR4.tsv
2009-QTR1.tsv
2009-QTR2.tsv
2009-QTR3.tsv
...
そして、grepした後、次のように保存する必要があります。
2008Q1.txt
2008Q2.txt
2008Q3.txt
2008Q4.txt
2009Q1.txt
2009Q2.txt
2009Q3.txt
何かご意見は?
Ksh93/bash/zshでは、単純なfor
ループとパラメーター展開を使用します。
for f in *-QTR*.tsv
do
grep 8-K < "$f" > "${f:0:4}"Q"${f:8:1}".txt
done
これは、一度に1つのファイルに対してgrep
を実行します(そのファイルのリストは、ファイル名に「-QTR」が存在し、ファイル名の末尾に「.tsv」が存在する必要があるワイルドカードパターンから生成されます)、以下に基づいて慎重に作成されたファイル名に出力をリダイレクトします。
Q
必須のPOSIX sh
バリアント:
#! /bin/sh -
ret=0
for file in [[:digit:]][[:digit:]][[:digit:]][[:digit:]]-QTR[1234].tsv; do
base=${file%.tsv}
grep 8-K < "$file" > "${base%%-*}Q${base##*-QTR}".txt || ret=$?
done
exit "$ret"
別のオプション
for f in 200{8..9}-QTR{1..4}.tsv; do
grep "pattern" $f > $(sed "s/[-RTtsv]*//g" <<< $f)txt;
done
チュートリアル:ファイル名のリストを作成する展開を設定する
200{8..9}-QTR{1..4}.tsv
に拡大する
2008-QTR1.tsv 2008-QTR2.tsv 2008-QTR3.tsv 2008-QTR4.tsv 2009-QTR1.tsv 2009-QTR2.tsv 2009-QTR3.tsv 2009-QTR4.tsv
そして、毎年、そして今までの四半期は、
20{08..19}-QTR{1..4}.tsv
リストを反復するfor..do..done
、探しているパターンをファイルから抽出します
grep "pattern" $f
そして、sed
で不要な文字を削除し、txt
サフィックスを追加することによって形成された新しいファイル名にリダイレクトします。
$(sed "s/[-RTtsv]*//g" <<< $f)txt
または
$(sed "s/[-RT]*//g" <<< ${f%%.*}.txt)
明示的なループを回避したい場合は、次の解決策があります。誰かがそれを改善できるかもしれません。こんな感じです。
ls -1 *.tsv | xargs -n1 -I'{}' bash -c 'f="{}";grep 8-K $f > ${f//[^0-9Q]/}.txt'
長所:-シンプルなワンライナー
短所:-処理されるファイルごとにbashプロセスが開始される
多分bashを使用せずに同様の解決策がありますが、私はそれを知りません(たとえば、evalはこのコンテキストでは機能しないはずです)