sed を使用してファイルを編集し、結果を元のファイル名に基づいて別のファイルに保存します。

sed を使用してファイルを編集し、結果を元のファイル名に基づいて別のファイルに保存します。

通常のファイル名パターンを使用して、長さが〜200,000行の.csvファイルの束(〜300個)があります。

outfile_n000.csv
outfile_n001.csv
outfile_n002.csv
.
.
.
outfile_nXXX.csv

各ファイルから行範囲(100013-200013)を抽出し、抽出した範囲を新しい.csvファイルに保存し、元のファイルを保持しながら元のファイルと区別するptally_ためにプレフィックスを追加する必要があります。

私は使用できることを知っています

sed -n '100013,200013p' outfile_nXXX.csv > ptally_outfile_nXXX.csv

単一ファイルに対してこれを行いますが、大規模ファイルの配置を自動化する方法が必要です。-isedのオプションを使用してこれを達成できます。

sed -iptally_* -n '100013,200013p' outfile_nXXX.csv > ptally_outfile_nXXX.csv

ただし、これは抽出された行を作成し、outfile_nXXX.csv元のファイルの名前を変更することptally_outfile_nXXX.csvです-i

同様に、中括弧拡張とワイルドカードを混在させることはできないため、bashの中括弧拡張は機能しません。

sed --n 10013,20013p *.csv > {,ptally_}*.csv

抽出と名前変更をより簡単なプロセスに組み合わせるエレガントな方法はありますか?現在私はbashスクリプトを使用してoutfile_nXXX.csvファイル名との間のやりとりをしていますが、ptally_outfile_nXXX.csvより簡単なワークフローを好みます。ありがとうございます!

答え1

ループを使用してくださいfor

for f in outfile_n???.csv; do
  sed -n '100013,200013p' "$f" > ptally_"$f"
done

あるいは、特定の実際の要件に応じて、以下を使用する方がより適切な場合があります。csplit。一部GNU拡張その力を大きく拡張してください。

答え2

いいえsed、しかし非常にエレガントな方法です。

awk 'NR >= 100013 && NR <= 200013 {print > "ptally_" FILENAME}' outfile_nXXX.csv

新しい適切なファイルに一括抽出するには:

awk 'FNR >= 100013 && FNR <= 200013 {print > "ptally_" FILENAME}' outfile_n*

あるいは、ファイル名を次に渡す前に変数に保存することもできますsed

filename="outfile_nXXX.csv"

sed -n '100013,200013p' "$filename" > "ptally_$filename"

関連情報