summaryrefslogtreecommitdiff
path: root/segment-file.sh
blob: 50f70b8c2ca64828b6c5d1100ed2f2b07333bc82 (plain)
    1 #!/usr/bin/env bash
    2 
    3 # Bash substring parse cheatsheet
    4 # -------------------------------
    5 #   %.*  filename.blah.foo.txt -> filename.blah.foo
    6 #   %%.* filename.blah.foo.txt -> filename
    7 #   #*.  filename.blah.foo.txt -> foo.blah.txt
    8 #   ##*. filename.blah.foo.txt -> txt
    9 
   10 
   11 
   12 # split:
   13 # Splits the specified file into the specified number of segments. Output file
   14 # is created within the 'out' directory.
   15 #
   16 # @file         Source file to split into multiple segments
   17 # @splitcount   Number of segments to split @file into.
   18 split() {
   19   local file="${1}"
   20   local splitcount="${2}"
   21 
   22   local lc="$(wc -l ${file} | cut -d ' ' -f 1)"
   23   local lps=$(( lc / splitcount + 1 ))  # Calculate lines per segment
   24   local segment=0                   # Current file segment int
   25   local segline=0                   # Current line in the current segment
   26   local outfile=''                  # Current output file segment path
   27 
   28   # Filename without extension (filename.txt -> filename)
   29   local filebase="${file%.*}"
   30   # File extension (filename.txt -> txt)
   31   local fileext=".${file##*.}"
   32 
   33   # If file extension is the same as the file base (with a preceeding dot), the
   34   # source file has no extention. Set this variable to empty so the extention
   35   # will be the segment number
   36   [ "${fileext}" = ".${filebase}" ] && fileext=''
   37 
   38   # Create output directory to keep things a bit more organized
   39   [ ! -d out ] && mkdir out
   40 
   41   # Ensure IFS is only separating on newlines
   42   local oldifs="${IFS}"
   43   export IFS=$'\n'
   44 
   45 
   46   # Update the outfile path
   47   outfile="out/${filebase}.${segment}${fileext}"
   48   # Truncate the current output segment file. If we skip this and the file
   49   # already exists, we will append to an existing file, corrupting output.
   50   > "${outfile}"
   51   printf "Writing to '%s' segment\n" "${outfile}"
   52 
   53 
   54   # Iterrate over the source file, line by line.
   55   for line in $(cat ${file}); do
   56     if [ "${segline}" -eq "${lps}" ]; then
   57       # Increment the file segment counter
   58       segment=$(( segment + 1 ))
   59       # Reset the segment line counter
   60       segline=0
   61 
   62       # Update the outfile path
   63       outfile="out/${filebase}.${segment}${fileext}"
   64       > "${outfile}"
   65       printf "Writing to '%s' segment\n" "${outfile}"
   66     fi
   67 
   68     # Append line to segment file
   69     printf -- "%s\n" "${line}" >> "${outfile}"
   70 
   71     # Increment the segment line counter so we can ensure we don't write past
   72     # the 'lines per segement' (lps) var.
   73     segline=$(( segline + 1 ))
   74   done
   75 
   76   export IFS="${oldifs}"
   77 }
   78 
   79 
   80 main() {
   81   local file="${1}"
   82   local count="${2}"
   83 
   84   # Ensure file and segment count are specified
   85   [ -z "${file}" ] && printf "Filename required\n" && return 1
   86   [ -z "${count}" ] && printf "Segment count required\n" && return 1
   87 
   88   # Split (Croatia)!
   89   split "${file}" "${count}"
   90 }
   91 
   92 main ${@}

Generated by cgit