NoobEditor
NoobEditor

Reputation: 15871

Read user given file character by character in bash

I have a file which is kind of unformatted, I want to place a new-line after every 100th character and remove any other new lines in it so that file may look with consistent width and readable

This code snippet helps read all the lines

 while read LINE
        do
                len=${#LINE}
                echo "Line length is : $len"
        done < $file

but how do i do same for characters

Idea is to have something like this : (just an example, it may have syntax errors, not implemented yet)

 while read ch  #read character
  do
         chcount++ # increment character count

    if [ "$chcount" -eq "100" && "$ch"!="\n" ] #if 100th character and is not a new line
    then
        echo -e "\n" #echo new line
    elif [ "$ch"=="\n" ]  #if character is not 100th but new line
        then
        ch=" " $replace it with space
     fi
  done < $file

I am learning bash, so please go easy!!

Upvotes: 6

Views: 18266

Answers (4)

user9156891
user9156891

Reputation:

#!/bin/bash
w=~/testFile.txt
chcount=0
while read -r word ; do
        len=${#word}
        for (( i = 0 ; i <= $len - 1 ; ++i )) ; do
                let chcount+=1
                if [ $chcount -eq 100 ] ; then
                        printf "\n${word:$i:1}"
                        let chcount=0
                else
                        printf "${word:$i:1}"
                fi
        done
done < $w

Are you looking for something like this?

Upvotes: 1

Dennis Williamson
Dennis Williamson

Reputation: 359935

You can call the function below in any of the following ways:

line_length=100
wrap $line_length <<< "$string"
wrap $line_length < file_name
wrap $line_length < <(command)
command | wrap $line_length

The function reads the input line by line (more efficiently than by character) which essentially eliminates the existing newlines (which are replaced by spaces). The remainder of the previous line is prefixed to the current one and the result is split at the desired line length. The remainder after the split is kept for the next iteration. If the output buffer is full, it is output and cleared otherwise it's kept for the next iteration so more can be added. Once the input has been consumed, there may be additional text in the remainder. The function is called recursively until that is also consumed and output.

wrap () { 
    local remainder rest part out_buffer line len=$1
    while IFS= read -r line
    do
        line="$remainder$line "
        (( part = $len - ${#out_buffer} ))
        out_buffer+=${line::$part}
        remainder=${line:$part}
        if (( ${#out_buffer} >= $len ))
        then
            printf '%s\n' "$out_buffer"
            out_buffer=
        fi
    done
    rest=$remainder
    while [[ $rest ]]
    do
        wrap $len <<< "$rest"
    done
    if [[ $out_buffer ]]
    then
        printf '%s\n' "$out_buffer"
        out_buffer=
    fi
}

Upvotes: 3

chepner
chepner

Reputation: 530960

bash adds a -n flag to the standard read command to specify a number of characters to read, rather than a full line:

while read -n1 c; do
    echo "$c"
done < $file

Upvotes: 7

devnull
devnull

Reputation: 123458

I want to place a new-line after every 100th character and remove any other new lines in it so that file may look with consistent width and readable

Unless you have a good reason to write a script, go ahead but you don't need one.

Remove the newline from the input and fold it. Saying:

tr -d '\n' < inputfile | fold -w 100

should achieve the desired result.

Upvotes: 7

Related Questions