LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Bash - string1 replaces part of string2 on concat (https://www.linuxquestions.org/questions/programming-9/bash-string1-replaces-part-of-string2-on-concat-940483/)

yzfr1 04-18-2012 11:44 AM

Bash - string1 replaces part of string2 on concat
 
Hello there,

This has confused the hell out of me for a while now, so here I am.

I have three arrays. Two with numbers and one with text. I'm trying to neatly print these three arrays out next to eachother, but here's where I get my problem.

The arrays look like this:

Code:

tsizes                fsizes                files
-----                -----                -----
1462417408        735940608        File 1
578531636        367489024        File 2
578517728        367593472        File 3
578452724        366977024        File 4
578439568        367568896        File 5
578448102        365772800        File 6
578424864        365948928        File 7
578448934        369041408        File 8
578452528        367218688        File 9
578440336        367177728        File 10
578421354        366243840        File 11
578425152        367912960        File 12
578445224        367144960        File 13
578432682        367065088        File 14
578439098        367116288        File 15
578430258        367112192        File 16
577640484        367028224        File 17
578073694        367198208        File 18
578432472        367226880        File 19
578448496        367321088        File 20
578438178        367347712        File 21

Now I'm trying to print it out in pretty much the same way as you see it above, separated with " | ". Printing the out one by one is no problem, but when I want them next to each other the problems start.

Here was my first attempt:
Code:

for (( i=0; i< ${#tsizes[@]}; i++ ))
do
        echo "${tsizes[$i]} | ${fsizes[$i]}$ | {ffiles[$i]}"
done

And here is the output from that:
Code:

| 735940608 | File 1
 | 367489024 | File 2
 | 367593472 | File 3
 | 366977024 | File 4
 | 367568896 | File 5
 | 365772800 | File 6
 | 365948928 | File 7
 | 369041408 | File 8
 | 367218688 | File 9
 | 367177728 | File 10
 | 366243840 | File 11
 | 367912960 | File 12
 | 367144960 | File 13
 | 367065088 | File 14
 | 367116288 | File 15
 | 367112192 | File 16
 | 367028224 | File 17
 | 367198208 | File 18
 | 367226880 | File 19
 | 367321088 | File 20
 | 367347712 | File 21

Ie, the first array isn't printed.
However, having the first array printed on its own in the loop does work. And when I try adding some random characters to print alone with the first array things get really weird:
Code:

for (( i=0; i< ${#tsizes[@]}; i++ ))
do
        echo  "${tsizes[$i]}test"
done

Output:
Code:

test417408
test31636
test17728
test52724
test39568
test48102
test24864
test48934
test52528
test40336
test21354
test25152
test45224
test32682
test39098
test30258
test40484
test73694
test32472
test48496
test38178

The word test is replacing the first four numbers!

Does anyone have an idea on why it would do that and how I can fix it?

Cheers!

grail 04-18-2012 12:09 PM

I would hazard a guess that the file where the 'arrays' are being read from was created in Windows and hence the line endings are incorrect.
Try running dos2nix over it or if not sure before you start try:
Code:

cat -A file
If they do not end in a $ sign then linux will not understand them (that is output of above command will show $ signs at the end if correct).

yzfr1 04-18-2012 12:21 PM

Damn, you are so right!

One of the arrays is part of a windows .txt file from a windows machine, read by
Code:

cat "$1" | cut -s -f3
I didn't know it would cause such problems just reading one column from the file, but there you go! Learn something new every day.

Thanks mate!

Nominal Animal 04-18-2012 03:34 PM

You could use
Code:

awk 'BEGIN { ORS="\n"; RS="[\t\v\f ]*(\r\n|\n\r|\r|\n)[\t\v\f ]*"; FS="[\t\v\f ]+" }
    { print $3 }' "$1"

instead of cat and cut; it accepts any newline convention, ignores leading and trailing whitespace, and outputs using Unix newlines only. You can easily add filters, too. For example, to do the same, but skip lines that begin with a # or a ;
Code:

awk 'BEGIN { ORS="\n"; RS="[\t\v\f ]*(\r\n|\n\r|\r|\n)[\t\v\f ]*"; FS="[\t\v\f ]+" }
    /^[#;]/ { next }
    { print $3 }' "$1"


yzfr1 04-18-2012 04:06 PM

Really need to learn some of that awk magic some day.

Thanks for the alternative mate, appreciate it.

David the H. 04-19-2012 11:53 AM

To add a couple of suggestions for your loop:

1) Assuming all the arrays have an equal number of entries (or you know which one will have the largest number), you can use "${!array[@]}" to output a list of all existing index numbers. This is particularly handy when you have sparse arrays (with missing indexes).

2) The '[]' index boxes in regular arrays (but not associative arrays) operate in an arithmetic environment, so you generally don't need to use '$' on variables. They'll expand automatically.

Code:

for i in "${!tsizes[@]}" ; do
        echo "${tsizes[i]} | ${fsizes[i]} | ${ffiles[i]}"
done

How can I use array variables?
http://mywiki.wooledge.org/BashFAQ/005


All times are GMT -5. The time now is 08:56 PM.