Why is the IFS value removed from the file while splitting?

Ammu
IFS=$'?\n'
for line in $(cat "./newfiletoread")
do printf "${line}\n"
done

The file contents are as below: Hello there!How are you doing?How is life?Mine is as boring as a winter morning!

The code above splits the contents of the file when it comes across a '?' or '!' or '/n' which is nice. But, during the expansion the shell removes these characters from the file. The below is the output that I get.

Hello there 
How are you doing
How is life
Mine is as boring as a winter morning

I understand that it is how shell works by substituting these IFS values with spaces before the command executes. Is there a way to preserve these delimiter characters during the splitting? I would like to get my output like this one below:

Hello there! 
How are you doing?
How is life?
Mine is as boring as a winter morning!
glenn jackman

First, don't read the lines of a file with for

I read this somewhere about splitting strings: use split when you know what to throw away; use a regular expression when you know what you want to keep. Or something like that.

The problem with using shell word splitting using $IFS is that any char in that variable is used to split, and you can't know which one.

With bash, you can write:

line='Hello there! How are you doing? How is life? Mine is as boring as a winter morning!'
line=${line//\?/$'"?\n'}
line=${line//\!/$'"!\n'}
echo "$line"
Hello there"!
 How are you doing"?
 How is life"?
 Mine is as boring as a winter morning"!

Note the leading spaces. That can be worked around with a more complicated pattern: line=${line//\?*([[:blank:]])/$'"?\n'}

I would use sed instead:

line='Hello there! How are you doing? How is life? Mine is as boring as a winter morning!'
new=$( sed 's/[?!][[:blank:]]*/&\n/g' <<<"$line" )
echo "$new"
Hello there! 
How are you doing? 
How is life? 
Mine is as boring as a winter morning!

has a split() function that does let you capture the separators, but using it is pretty verbose:

echo "$line" | awk '{
    n = split($0, words, /[!?][[:blank:]]*/, seps)
    for (i = 1; i < n; i++) 
        print words[i] seps[i]
    print words[n]}
'

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Why is IFS=; different from IFS=";"?

Is it possible to "protect" an IFS character from field splitting?

Why classifier is removed from artifact while installing on local maven repo?

Getting ArrayIndexOutOfBoundsException while splitting record from a file in Scala

In `while IFS= read..`, why does IFS have no effect?

Why am I getting a value error in excel while using the ifs function?

Splitting symbols from a file

Why file path string is not splitting

Why is `while IFS= read` used so often, instead of `IFS=; while read..`?

Why was ffmpeg removed from Debian?

Splitting Apache Log from File

Splitting data from text file

Out of bounds error, while reading file then splitting it

Value not being removed from dictionary

.nuspec file was removed and .nupkg file was created . Why?

newlines also removed by splitting

Replacing value inside while loop with using sed and IFS

What does IFS= do in this bash loop: `cat file | while IFS= read -r line; do ... done`

Remove Whitespace from strings while Splitting by ","

Why are my new-line characters '\n' being removed from my csv file at download?

Splitting lines read from file into array of key-value pairs in Erlang

why doesn't bash IFS value split expansion argument?

Set value and clear value in batch while reading from file in windows

Why is a link removed when disabling a service? (a file is not)

JavaScript splitting a file content into key value pairs

Splitting csv file based on column value <SOLVED>

Why doesn't the separator from IFS work for array expansion?

Why is "_" getting removed from a number in javascript?

Why was await* removed from the async/await proposal?