如何分割文件,并保持第一行中的每个碎片的?(How to split a file and keep

2019-07-17 18:44发布

鉴于:一个大的文本数据文件(例如,CSV格式)用“特殊”第一线(例如,字段名)。

通缉:所述的coreutils的等效split -l命令,但与从原始文件中的标题行出现在每个所得到的片的起点的附加要求。

我猜测的一些药汁splithead会做的伎俩?

Answer 1:

这是robhruska的剧本清理了一下:

tail -n +2 file.txt | split -l 4 - split_
for file in split_*
do
    head -n 1 file.txt > tmp_file
    cat "$file" >> tmp_file
    mv -f tmp_file "$file"
done

我删除wccutlsecho在他们不必要的地方。 我改变了一些文件名,使他们多一点有意义的。 我打破了它在多行只以使其更易于阅读。

如果你想获得幻想,你可以使用mktemptempfile创建一个临时文件名,而不是使用硬编码的一个。

编辑

使用GNU split有可能做到这一点:

split_filter () { { head -n 1 file.txt; cat; } > "$FILE"; }; export -f split_filter; tail -n +2 file.txt | split --lines=4 --filter=split_filter - split_

拆开进行可读性:

split_filter () { { head -n 1 file.txt; cat; } > "$FILE"; }
export -f split_filter
tail -n +2 file.txt | split --lines=4 --filter=split_filter - split_

--filter被指定时, split运行用于每个输出文件的命令(在此情况下的函数,其必须导出),并将可变FILE ,在命令的环境,到文件名。

过滤器的脚本或函数可以做它想输出的内容,甚至是文件名的任何操作。 后者的一个例子可能是输出到在一个变量目录的固定文件名: > "$FILE/data.dat"例如。



Answer 2:

你可以在GNU的coreutils分割使用新的--filter功能> = 8.13(2011年):

tail -n +2 FILE.in |
split -l 50 - --filter='sh -c "{ head -n1 FILE.in; cat; } > $FILE"'


Answer 3:

You can use [mg]awk:

awk 'NR==1{
        header=$0; 
        count=1; 
        print header > "x_" count; 
        next 
     } 

     !( (NR-1) % 100){
        count++; 
        print header > "x_" count;
     } 
     {
        print $0 > "x_" count
     }' file

100 is the number of lines of each slice. It doesn't require temp files and can be put on a single line.



Answer 4:

我是一个新手,当谈到猛砸福,但我能炮制这两个命令的怪物。 我敢肯定有更优雅的解决方案。

$> tail -n +2 file.txt | split -l 4
$> for file in `ls xa*`; do echo "`head -1 file.txt`" > tmp; cat $file >> tmp; mv -f tmp $file; done

这是假设你的输入文件file.txt ,你不使用的prefix参数来split ,而你在不具有与启动任何其他文件的目录工作split的默认xa*输出格式。 另外,与你的期望分割线的尺寸更换“4”。



Answer 5:

这会在每一个的顶部的大的csv分成999线件,与头

cat bigFile.csv | parallel --header : --pipe -N999 'cat >file_{#}.csv'

基于OLE丹的回答。 (重新奥莱的回答是:你不能使用符合pipepart计数)



Answer 6:

这是丹尼斯·威廉姆森的剧本中一个更强大的版本。 该脚本创建了大量的临时文件,如果他们离开躺在附近,如果运行是不完整的,将是一种耻辱。 所以,让我们上路信号捕捉(见http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_12_02.html然后http://tldp.org/LDP/abs/html/debugging.html )和除去我们的临时文件; 这是反正是最佳做法。

trap 'rm split_* tmp_file ; exit 13' SIGINT SIGTERM SIGQUIT 
tail -n +2 file.txt | split -l 4 - split_
for file in split_*
do
    head -n 1 file.txt > tmp_file
    cat $file >> tmp_file
    mv -f tmp_file $file
done

与任何你想要返回的代码替换“13”。 哦,你或许应该使用mktemp的反正(如某些人已经建议),所以,尽管从陷阱行RM删除“tmp_file”,更多的信号捕捉见信号手册。



Answer 7:

我无法知道从其他人的网站直复制脚本的规则,但Geekology有一个很好的脚本,做你想要的东西,有一些意见确认其有效。 务必做到tail -n +2在靠近底部的评论指出。



Answer 8:

我很喜欢马可AWK版本,从这个简单的一行代码采纳,你,你想要可以很容易地指定分割部分粒状:

awk 'NR==1{print $0 > FILENAME ".split1";  print $0 > FILENAME ".split2";} NR>1{if (NR % 10 > 5) print $0 >> FILENAME ".split1"; else print $0 >> FILENAME ".split2"}' file


Answer 9:

我真的很喜欢Rob和丹尼斯的版本,以至于我想改善他们。

这里是我的版本:

in_file=$1
awk '{if (NR!=1) {print}}' $in_file | split -d -a 5 -l 100000 - $in_file"_" # Get all lines except the first, split into 100,000 line chunks
for file in $in_file"_"*
do
    tmp_file=$(mktemp $in_file.XXXXXX) # Create a safer temp file
    head -n 1 $in_file | cat - $file > $tmp_file # Get header from main file, cat that header with split file contents to temp file
    mv -f $tmp_file $file # Overwrite non-header containing file with header-containing file
done

区别:

  1. in_file中是要分割保持头文件参数
  2. 使用awk ,而不是tail由于awk具有更好的性能
  3. 拆分为10万个文件,而不是4
  4. 分割文件名会用下划线和数字输入附加文件名(最多99999 - 从“-d -a 5”分裂的说法)
  5. 使用mktemp的安全地处理临时文件
  6. 使用单head | cat head | cat行,而不是两行


Answer 10:

使用GNU并行:

parallel -a bigfile.csv --header : --pipepart 'cat > {#}'

如果你需要在每个部件的运行命令,然后GNU并行可以帮助做到这一点,太:

parallel -a bigfile.csv --header : --pipepart my_program_reading_from_stdin
parallel -a bigfile.csv --header : --pipepart --fifo my_program_reading_from_fifo {}
parallel -a bigfile.csv --header : --pipepart --cat my_program_reading_from_a_file {}

如果要分割成2份每个CPU核心(例如24个核心= 48个尺寸相等的份数):

parallel --block -2 -a bigfile.csv --header : --pipepart my_program_reading_from_stdin

如果你想分成10个MB块:

parallel --block 10M -a bigfile.csv --header : --pipepart my_program_reading_from_stdin


Answer 11:

下面是可以用来保存CSV报头中的4衬垫(使用:头部,分割,发现,grep的,xargs的,和SED)


csvheader=`head -1 bigfile.csv`
split -d -l10000 bigfile.csv smallfile_
find .|grep smallfile_ | xargs sed -i "1s/^/$csvheader\n/"
sed -i '1d' smallfile_00

说明:

  • 捕获的头一个变量命名csvheader
  • 拆分大文件分成若干较小的文件(前缀smallfile_)
  • 找到所有smallfiles并插入到csvheader xargs的使用和sed -i的第一道防线。 请注意,您需要使用,以使用变量“双引号”内的sed。
  • 第一文件名为smallfile_00现在将对线路1和2(从原始数据,以及从在步骤3中的sed头插入)冗余标题。 我们可以删除与SED -i“1D”命令冗余头。


文章来源: How to split a file and keep the first line in each of the pieces?