Operating System - Linux
1822895 Members
4087 Online
109645 Solutions
New Discussion юеВ

IFS Internal Field Separator

 
SOLVED
Go to solution
Tracy_33
Occasional Advisor

IFS Internal Field Separator

$#using ksh on 11i, I need to set IFS to a
$#newline inside a script (to preserve tabs,
$#leading spaces, whatever). Interactively,
$IFS=" #<---- nothing invisible except CR
>" #<---- ditto.
$#this works ok, too, and
$echo $IFS | od -b
0000000 012
0000001
$#LOOKS almost as I'd expect, though I'm told $#that echo added the 012 (LF) I don't $#believe it - there'd be one on the next $#line too, right? Anyway, I'd like to do $#this in a script, where you can't see $#what's typed and probably can't remember $#either, so it would be really nice to be
$#visibly specify exactly what I want, such
$#as
$IFS=%012 #or better imho...
$IFS=$0A

$#I tried
$IFS=\n
$#and very curiously get the same result from $echo IFS | od -b
$# but it sure doesn't work!



TIA
9 REPLIES 9
Hein van den Heuvel
Honored Contributor

Re: IFS Internal Field Separator

Hi there,

You did not get any suggestion so far, perhaps because forum performance has been spotty (being nice here :-), or perhaps because your topic looks a little confusing (beging nice here :-).

Anyway...
For a simple discussion on IFS try: Google +shell +ifs [I'm feeling lucky]
But you seem to know that already.

What problem are you really trying to solve?
As much as I like reduced, simplyfied examples you may have oversimplyfied and lost the point in your description.
There may be better tools (awk, perl,...) that avoid the word breaks.

Maybe, just mabye, your problem is solved by just assigning IFS to nothing?

Example (similar to that liverfile example):

# line="learn unix at livefire labs"
# for i in $line
> do
> echo $i
> done
learn
unix
at
livefire
labs
# IFS=
# for i in $line
> do
> echo $i
> done
learn unix at livefire labs
#


KISS!

Hein.
Tracy_33
Occasional Advisor

Re: IFS Internal Field Separator

OK, a little simpler:

Is there an unambiguous way to express control characters to the Posix shell?

I'd like something like

IFS=%012 # Octal 012, a LineFeed char.
IFS=$0A # Hex 0A, same character.
IFS=ascii(10) #again same character.

which would be handy not only for clearly setting IFS but also for clearly restoring it!
Rodney Hills
Honored Contributor
Solution

Re: IFS Internal Field Separator

The typical way under the shell would be-

bs=`echo "\010"`

However, since linefeed is a special character used for record seperation within text files, I don't think it's going to work.

If you set IFS to null, then I think you will get the results you are looking for.

perl or awk might be better tools for string processing of a file.

HTH

-- Rod Hills
There be dragons...
Tracy_33
Occasional Advisor

Re: IFS Internal Field Separator

DING! a correct and specific answer, thanks; but now there's more.

$IFS="\012"
should work to set IFS = linefeed aka newline, but no...
$ IX="
> "
$ echo $IX | od -b
0000000 012 012
0000002
$ IX="\012"
$ echo $IX | od -b
0000000 134 040 040 012
0000004
but
$ IX="\001\002\003\004\005\006\007\010\012\013\014\015\020"
$ echo $IX | od -b
0000000 001 002 003 004 005 006 007 010 012 013 014 015 020 012
0000016
$# what's happening here?
$# and shouldn't IFS typically be \040\011\012 (space,tab,linefeed)? mine seems to default to , not even \000.
James R. Ferguson
Acclaimed Contributor

Re: IFS Internal Field Separator

Hi:

If you simply unset IFS you will preserve leading spaces and tabs upon reading. No word splitting is done:

#!/usr/bin/sh
OLDIFS=${IFS}
IFS=
while read LINE
do
echo ${LINE}
done
IFS=${OLDIFS}

Does this help?

Regards!

...JRF...
Tracy_33
Occasional Advisor

Re: IFS Internal Field Separator

$# Yes that helps; both
$oldIFS=$IFS #good idea
$# and
$IFS=
$# are good; using that IFS setting works. so my questions become entirely academic, no quick answers:

1) in the HPUX shell user guide (posix section) the intro says IFS behavior is different from Bourne, "IFS variable is effective only for read, results of parameter expansions and command substitution; it is always initialized."
and later in a table "Shell parms" it says
"IFS:Internal Field Separators (usually space, tab, and new-line), which are used to separate command words during command or parameter substitution and when using the read command." OK, let's test that:
$sh
$echo $IFS | od -b
0000000 012
0000001
$# I see nothing here; does that mean od -b doesn't work?
$read line
3spacesthentabhere: thenspacehere: theend.
$echo $line
3spacesthentabhere: thenspacehere: theend.
$# so spaces and tabs are being removed, but why? I sure didn't see them in IFS.
$IFS=
$echo $IFS | od -b
0000000 012
0000001
$read line
3spacesthentabhere: thenspacehere: theend.
$echo $line
3spacesthentabhere: thenspacehere: theend.
$# it's working now. why?
$# also, what's happening here?:
$IFS=
$read line
tab3spacesthenthisthentab: thenthisthentab: theend.
$echo $line
tab3spacesthenthisthentab: thenthisthentab: theend.
$echo $IFS | od -b
0000000 012
0000001
$IFS="\011\012\040"
$echo $IFS | od -b
0000000 134 040 040 040 134 040 040 040 134 040 040 012
0000014
$#WTF?
$IFS="
> "
$echo $IFS | od -b
0000000 012
0000001
$IFS="\011\012"
$echo $IFS | od -b
0000000 134 040 040 040 134 040 040 012
0000010
$#I have examples of \011 really being loaded to IFS, but not always. any clues?
$#I'm about to start smoking again.
Rodney Hills
Honored Contributor

Re: IFS Internal Field Separator

Space, tab, and new-line are special to the shell too.

Try-
echo "$IFS" | od -b

to see the contents.

Rod Hills
There be dragons...
Tracy_33
Occasional Advisor

Re: IFS Internal Field Separator

That last answer's pretty short but a lot to chew. Thanks!
Tracy_33
Occasional Advisor

Re: IFS Internal Field Separator

sorry it took so long to pound echo's function into my thick skull.