2

I'm building a function to find large directories on the filesystem and the /n is being cut off of /native/proc... in each of my array elements containing that path. I believe this has something to do with me using "\n" as my IFS but I'm not sure how else to do it because without that it breaks each column into it's own element which is not what I want. What I need is for each full line to be in it's own array element sort of how the command prints out on it's own:

[root@JBLGSMM001 ~]# du -k / 2> /dev/null | sort -n | tail -n 10
255452  /usr/share
332644  /native/proc/82974
342119  /native/proc/70315
344519  /native/proc/70310
388510  /native/usr
683983  /usr
1226993 /native/proc/45026
9597039 /native/proc
10035430        /native
10846908        /

Function so far

where.isdisk () {

    bigstuff=$(du -k / 2> /dev/null | sort -n | tail -n 10)
    OLDIFS=$IFS
    IFS="\n"
    bigstuff=($bigstuff)
    IFS=$OLDIFS

}

The bigstuff variable gets set as I want with the following:

255452 /usr/share 332644 /native/proc/82974 342119 /native/proc/70315 344519 /native/proc/70310 388510 /native/usr 683983 /usr 1226989 /native/proc/45026 9772351 /native/proc 10210742 /native 11022217 /

Then when I create the array it trims the "/n"s out:

[root@JBLGSMM001 ~]# OLDIFS=$IFS
[root@JBLGSMM001 ~]# IFS="\n"
[root@JBLGSMM001 ~]# bigstuff=($bigstuff)
[root@JBLGSMM001 ~]# IFS=$OLDIFS
[root@JBLGSMM001 ~]# echo ${bigstuff[@]}
255452 /usr/share 332644 / ative/proc/82974 342119 / ative/proc/70315 344519 / ative/proc/70310 388510 / ative/usr 683983 /usr 1226989 / ative/proc/45026 9772351 / ative/proc 10210742 / ative 11022217 /

EDIT

It's also carrying over the "/" to the previous element:

[root@JBLGSMM001 ~]# echo ${bigstuff[0]}
255452 /usr/share 332644 /
[root@JBLGSMM001 ~]# echo ${bigstuff[1]}
ative/proc/82974 342119 /
[root@JBLGSMM001 ~]# echo ${bigstuff[2]}
ative/proc/70315 344519 /
[root@JBLGSMM001 ~]# echo ${bigstuff[3]}
ative/proc/70310 388510 /

EDIT 2

I've tried replacing \n with \012 but it still produces undesired results:

[root@JBLGSMM001 ~]# bigstuff=$(du -k / 2> /dev/null | sort -n | tail -n 10)
[root@JBLGSMM001 ~]# OLDIFS=$IFS
[root@JBLGSMM001 ~]# IFS="\012"
[root@JBLGSMM001 ~]# bigstuff=($bigstuff)
[root@JBLGSMM001 ~]# IFS=$OLDIFS
[root@JBLGSMM001 ~]# echo ${bigstuff[@]}
5545 /usr/share 33 644 /native/proc/8 974 34 9 /native/proc/7 3 5 3445 9 /native/proc/7 3 3885 /native/usr 683983 /usr 6989 /native/proc/45 6 977 387 /native/proc 778 /native 55 /
[root@JBLGSMM001 ~]# echo ${bigstuff[0]}

[root@JBLGSMM001 ~]# echo ${bigstuff[1]}
5545
[root@JBLGSMM001 ~]# echo ${bigstuff[2]}
/usr/share 33
[root@JBLGSMM001 ~]# echo ${bigstuff[3]}
644 /native/proc/8

Anyone know how to fix this? Thanks!

  • 3
    You should consider using mapfile (or its synonym readarray) to construct the array directly from a process substitution - that way you can skip the string altogether. See for example (with find rather than du) bash: whitespace-safe procedural use of find into select – steeldriver Aug 6 '17 at 14:03
  • Thanks! I've modified it to: IFS= mapfile -t bigstuff < <(du -k / 2> /dev/null | sort -n | tail -n 10) and it's working perfectly. – Jesse_b Aug 6 '17 at 14:24
  • 2
    To print the array with newlines, do: printf "%s\n" "${bigstuff[@]}" – glenn jackman Aug 6 '17 at 16:11
1

The shell won't interpret \n in IFS as newline but as the character n (escaped, which does nothing here). Notice that the / in front of the n is not removed.

To set IFS to a newline character, use

IFS='
'

In shells that understands "C strings" (bash being one of them), you may also use

IFS=$'\n'

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.