毎回異なるファイル名にリダイレクトされる複数のファイルを Grep

毎回異なるファイル名にリダイレクトされる複数のファイルを Grep

.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

どんなアイデアがありますか?

答え1

ksh93/bash/zshで単純なforループとパラメータ拡張を介して:

for f in *-QTR*.tsv
do 
  grep 8-K < "$f" > "${f:0:4}"Q"${f:8:1}".txt
done

今回はgrep、ファイル(ファイル名に「-QTR」とファイル名の末尾に「.tsv」が必要なワイルドカードパターンに基づいてファイルリストが生成されます)を実行すると、出力がファイルにリダイレクトされます。名前に基づいて慎重に構成されています。

  • ファイル名の最初の4文字 - 年
  • この手紙Q
  • ファイル名の9番目の文字 - Quarter

答え2

必須POSIXshバリアント:

#! /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"

答え3

その他のオプション

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)

答え4

明示的なループを回避するには、次の回避策があります。たぶん誰かがそれを改善することができます。こんな感じです。

ls -1 *.tsv | xargs -n1 -I'{}' bash -c 'f="{}";grep 8-K $f > ${f//[^0-9Q]/}.txt'
  1. エルエス処理したいファイルのみを一覧表示
  2. パラメータこれらの各ファイルを1つずつ処理します(-n1)
  3. 強く打つ文字列を処理できるようにシェルを起動します(ポイント5を参照)。
  4. ファイル名を変数に設定$f
  5. ${f//[^0-9Q]/}.txtファイル名に不要な文字を削除します(これはあなたの例にのみ当てはまります)。

利点: - シンプルなワンライナー

欠点: - 処理されたファイルごとにbashプロセスを開始します。

Bashを使用しない同様の解決策があるかもしれませんが、よくわかりません。

関連情報