内容に応じてテキストファイルを複数のテキストファイルに分割するには?

内容に応じてテキストファイルを複数のテキストファイルに分割するには?

次の内容を含むCAMS.txtというテキストファイルがあります。

4153999999999991
4153999999999992
4153999999999993
4153999999999994
4801999999999991
4801999999999992
4801999999999993

CAMS.txt ファイルを CAMS1.txt と CAMS2.txt という 2 つのファイルに分割したいと思います。その内容は次のとおりです。

CAMS1.txt

4153999999999991
4153999999999992
4153999999999993
4153999999999994

CAMS2.txt

4801999999999991
4801999999999992
4801999999999993

実際、元のCAMS.txtファイルの最初の4桁に基づいてファイルを分割します。常に4153と4801です。私はUNIXの世界に初めて触れました=)

答え1

awk '/^4153/ {print >"CAMS1.TXT"; next} {print >"CAMS2.TXT"}' CAMS.TXT

これを行う他の方法があります。別の方法は、2つのgrepコマンドを使用することです。

grep "^4153" CAMS.TXT > CAMS1.TXT
grep -v "^4153" CAMS.TXT > CAMS2.TXT

これはあまり効率的ではありませんが、入力が簡単で、最初のgrepが完了したら、シェル履歴で(「上」矢印キーを使用して)これを呼び出していくつかの変更を行うことができます。もちろん、ファイルを2回読み取るので、ファイルが大きい場合はこれをしないでください。

答え2

すでにテキストを知っている特別な場合は、次のようにできます。

while read line; do 
    [[ $line =~ ^4153 ]] && 
        printf "%s\n" "$line" >> CAMS1.TXT || 
        printf "%s\n" "$line" >> CAMS2.TXT 
done < CAMS.TXT 

CAMS.TXTこれは各行を変数として読み込み$line$line4153で始まる場合はCAMS1として印刷し、そうでない場合はCAMS2として印刷します。

または、最初の数字に基づいて各行を標準エラーまたは標準出力として印刷し、それに応じてコマンドの出力をリダイレクトすることもできます。たとえば、

perl -ne '/^4153/ ? print STDOUT : print STDERR' CAMS.TXT >CAMS1.TXT 2>CAMS2.TXT 

テキストが何であるかわからない場合は、行の最初の4文字の名前を持つファイルに各行を書き込むことができます。

awk '{print >> substr($1,1,4)}' CAMS.TXT 

4153上記のコマンドは、それぞれ4801予想される行を含む2つのファイルを生成します。これはさまざまなモードを処理できるという利点があります。

答え3

ここは純粋ですbash変形terdonより一般的なソリューション

while read line; do 
  echo "$line" >> "${line:0:4}.txt"
done < CAMS.txt

結果ファイルの名前は、例の入力4153.txtなど、各行の最初の4文字に基づいて指定されます。4801.txt

次のコードスニペットを使用すると、生成されたファイルの名前をCAMS1.txt一括して変更できますCAMS2.txt(元の入力の各行の最初の4文字が実際には数字であると仮定します)。

i=1
for file in [0-9][0-9][0-9][0-9].txt; do
  mv "$file" "CAMS$(( i++ )).txt"
done

これは、元の入力ファイルの数が昇順であり、サンプル出力ファイルのファイル番号がこの順序に対応するという観察に依存します。

説明する:

while read line; do 
  ...
done < CAMS.txt

ファイルを繰り返しながら、CAMS.txt各行を順番に変数として読み込みますline

echo "$line" >> "${line:0:4}.txt"

現在行の最初の4文字から名前を取ったファイルに、現在処理中の行を追加します。


i=1

1変数に値を割り当てますi

for file in [0-9][0-9][0-9][0-9].txt; do
  ...
done

名前に4桁の数字が含まれ、.txt拡張子で終わる現在のディレクトリのファイルを繰り返します。上記のコードスニペットでは[0-9][0-9][0-9][0-9].txtShellと呼ばれます。全体的な状況。この機能は、特定の種類のパターン(この場合はファイル名)を一致または拡張するために使用できます。

mv "$file" "CAMS$(( i++ )).txt"

現在処理中のファイルの名前を変更しますfile。ターゲットファイル名"CAMS$(( i++ )).txt"は、CAMS変数の現在の値に関連付けられたプレフィックスで構成されます。i変数はi変数内で同時にインクリメントされます。bash 算術表現構文に示されているように、(( ... ))後続増分演算子を使用します++$上記の追加により、(( ... ))式の値が生成されます。この場合i 今後宛先ファイル名を表す文字列に拡張される増分です。最後に、.txtターゲットファイル名にサフィックスを追加します。

関連情報