Home > OS >  split a large file in multiple files but without case statement
split a large file in multiple files but without case statement

Time:11-20

I'm new in bash scripting and I'm trying to make a script which split a large file in multiple files. I succeeded with case statement but how can I make it without case statement? For example If I have a file with 30 millions of lines (some database file). Thank you in advance!

echo File which one you want to split
read pathOfFile
echo
countLines=`wc -l < $pathOfFile`
echo The file has $countLines lines
echo
echo In how many files do you want to split?
echo -e "a = 2 files\nb = 3 files\nc = 4 files\nd = 5 files\ne = 10 files\nf = 25 files"
read numberOfFiles
echo
echo The files name with should start:
read nameForFiles
echo

#Split the file
case $numberOfFiles in
a) split -l $(($countLines / 2)) $pathOfFile $nameForFiles;;
b) split -l $(($countLines / 3)) $pathOfFile $nameForFiles;;
c) split -l $(($countLines / 4)) $pathOfFile $nameForFiles;;
d) split -l $(($countLines / 5)) $pathOfFile $nameForFiles;;
e) split -l $(($countLines / 10)) $pathOfFile $nameForFiles;;
f) split -l $(($countLines / 25)) $pathOfFile $nameForFiles;;
*) echo Invalid choice.
esac

CodePudding user response:

With bash 4 you can use associative arrays:

#!/bin/bash

# ...

echo "In how many files do you want to split?"
printf '%s = %s files\n' a 2 b 3 c 4 d 5 e 10 f 25
read numberOfFiles

# Associative array for translating a letter to a number
declare -A aarr=([a]="2" [b]="3" [c]="4" [d]="5" [e]="10" [f]="25")

# Check that the supplied letter exists in the array
[[ ${numberOfFiles: X} ]] && [[ ${aarr["$numberOfFiles"] X} ]] || exit 1

# Translate the input to the corresponding value
numberOfFiles=${aarr["$numberOfFiles"]}

# ...

# Split the file
split -l "$((countLines < numberOfFiles ? 1 : countLines / numberOfFiles))" "$pathOfFile" "$nameForFiles"

CodePudding user response:

You can just use an array to store values then convert your character to an integer to use as an index:

# ...

z=('2' '3' '4' '5' '10' '25')
x=$(( $(printf '%d' "'$numberOfFiles") -97 ))

if  [[ $x -lt "${#z[@]}" ]] && [[ $x -ge '0' ]] ; then
    split -l $(($countLines / ${z[x]})) $pathOfFile $nameForFiles
else
    echo "Invalid choice"
fi

As you can see just convert character to ascii then minus 97 will ensure index lines up with range of z=('2' '3' '4' '5' '10' '25').

  • Related