web-dev-qa-db-ja.com

個々の行を分割せずに、ファイルを等しい部分に分割する方法は?

行を分割することなく、ファイルを等しい部分に分割することが可能かどうか疑問に思っていました(edit: = =最後を除いてすべて等しい)? Unixでsplitコマンドを使用すると、行が半分に分割される場合があります。たとえば、ファイルを5つの等しい部分に分割する方法はありますが、それでも行全体のみで構成されていますか(ファイルの1つが少し大きくても小さくても問題ありません)?行数を計算するだけでよいことはわかっていますが、bashスクリプトの多くのファイルに対してこれを行う必要があります。どうもありがとう!

99
Abdel

等しい数のlines、splitには、このオプションがあります:

split --lines=75

その75N等しい部分に対して本当に必要なものを知る必要がある場合、その:

lines_per_part = int(total_lines + N - 1) / N

wc -lで合計行を取得できます。

例については、次のスクリプトを参照してください。

#!/usr/bin/bash

# Configuration stuff

fspec=qq.c
num_files=6

# Work out lines per file.

total_lines=$(wc -l <${fspec})
((lines_per_file = (total_lines + num_files - 1) / num_files))

# Split the actual file, maintaining lines.

split --lines=${lines_per_file} ${fspec} xyzzy.

# Debug information

echo "Total lines     = ${total_lines}"
echo "Lines  per file = ${lines_per_file}"    
wc -l xyzzy.*

この出力:

Total lines     = 70
Lines  per file = 12
  12 xyzzy.aa
  12 xyzzy.ab
  12 xyzzy.ac
  12 xyzzy.ad
  12 xyzzy.ae
  10 xyzzy.af
  70 total

splitのより新しいバージョンでは、-n/--numberオプションでいくつかのCHUNKSを指定できます。したがって、次のようなものを使用できます。

split --number=l/6 ${fspec} xyzzy.

(つまり、ell-slash-sixであり、one-slash-sixではなく、linesを意味します)。

これにより、サイズの点でほぼ同等のファイルが得られ、中間の分割はありません。

最後の点に言及しますが、それは各ファイルでおおよそ同じ数のを与えておらず、より多くの同じ数の文字を与えていないからです。

したがって、1つの20文字行と19の1文字行(合計20行)があり、5つのファイルに分割されている場合、ほとんどの場合wo n'tすべてのファイルで4行を取得します。

135
paxdiablo

スクリプトは必要ありません。 split(1) はすぐに必要な機能をサポートします。
split -l 75 auth.log auth.log.上記のコマンドは、ファイルを1行75行のチャンクに分割し、次の形式でファイルを出力します。auth.log.aa, auth.log.ab, ...

元のファイルと出力のwc -lは以下を提供します。

  321 auth.log
   75 auth.log.aa
   75 auth.log.ab
   75 auth.log.ac
   75 auth.log.ad
   21 auth.log.ae
  642 total
38
jbr

splitは、coreutilsリリース8.8(2010年12月22日発表)で、-numberオプションを使用して特定の数のファイルを生成するように更新されました。オプション--number = l/nは、行を分割せずにn個のファイルを生成します。

http://www.gnu.org/software/coreutils/manual/html_node/split-invocation.html#split-invocationhttp://savannah.gnu.org/forum/ forum.php?forum_id = 6662

20
user3769065

簡単な質問の簡単な解決策:

split -n l/5 your_file.txt

ここでスクリプトを作成する必要はありません。

man ファイルから、CHUNKS may be:

l/N     split into N files without splitting lines

更新

すべてのUNIX distにこのフラグが含まれているわけではありません。たとえば、OSXでは機能しません。これを使用するには、 Mac OS XユーティリティをGNUコアユーティリティに置き換える を検討できます。

15
Kuf

入力としていくつかのパーツを指定し、ファイルを分割するbashスクリプトを作成しました

#!/bin/sh

parts_total="$2";
input="$1";

parts=$((parts_total))
for i in $(seq 0 $((parts_total-2))); do
  lines=$(wc -l "$input" | cut -f 1 -d" ")
  #n is rounded, 1.3 to 2, 1.6 to 2, 1 to 1
  n=$(awk  -v lines=$lines -v parts=$parts 'BEGIN { 
    n = lines/parts;
    rounded = sprintf("%.0f", n);
    if(n>rounded){
      print rounded + 1;
    }else{
      print rounded;
    }
  }');
  head -$n "$input" > split${i}
  tail -$((lines-n)) "$input" > .tmp${i}
  input=".tmp${i}"
  parts=$((parts-1));
done
mv .tmp$((parts_total-2)) split$((parts_total-1))
rm .tmp*

headおよびtailコマンドを使用し、ファイルを分割するためにtmpファイルに保存しました

#10 means 10 parts
sh mysplitXparts.sh input_file 10

またはawkの場合、0.1は10%=> 10パーツ、または0.334は3パーツです

awk -v size=$(wc -l < input) -v perc=0.1 '{
  nfile = int(NR/(size*perc)); 
  if(nfile >= 1/perc){
    nfile--;
  } 
  print > "split_"nfile
}' input
var dict = File.ReadLines("test.txt")
               .Where(line => !string.IsNullOrWhitespace(line))
               .Select(line => line.Split(new char[] { '=' }, 2, 0))
               .ToDictionary(parts => parts[0], parts => parts[1]);


or 

    enter code here

line="[email protected][email protected]";
string[] tokens = line.Split(new char[] { '=' }, 2, 0);

ans:
tokens[0]=to
token[1][email protected][email protected]"
1
Prabu