0

I have some code similar to this:

while read -r col1 col2 col3 col4 col5 col6 col7 col8 TRASH; do 
        echo -e "${col1}\n${col2}\n${col3}\n${col4}\n${col5}\n${col6}\n"
done< <(ll | tail -n+2 | head -2)

(I'm not actually using ls / ll but I believe this redacted example displays the same issue I am having)

The problem is I need a conditional statement if ll | tail -n+2 | head -2 fails so I'm trying to create a mapfile instead and then read through it in a script. The mapfile gets created properly but I don't know how to redirect it in order to be properly read.

code

if ! mapfile -t TEST_ARR < <(ll | tail -n+2 | head -2); then
        exit 1
fi
while read -r col1 col2 col3 col4 col5 col6 col7 col8 TRASH; do 
        echo -e "${col1}\n${col2}\n${col3}\n${col4}\n${col5}\n${col6}\n"
done<<<"${TEST_ARR[@]}"

mapfile contents

declare -a TEST_ARR=(
        [0]="drwxr-xr-x@ 38 wheel   1.2K Dec  7 07:10 ./" 
        [1]="drwxr-xr-x  33 wheel   1.0K Jan 18 07:05 ../"
)

output

$ while read -r col1 col2 col3 col4 col5 col6 col7 col8 TRASH; do
>             echo -e "${col1}\n${col2}\n${col3}\n${col4}\n${col5}\n${col6}\n"
>     done<<<"${TEST_ARR[@]}"
drwxr-xr-x@
38
wheel
1.2K
Dec
7

String redirect is clearly wrong in this case but I'm not sure how else I can redirect my array.

  • Don't Parse ls – cas Jan 20 '18 at 2:59
  • @cas Please read my post. – Jesse_b Jan 20 '18 at 11:14
  • I read it, and saw you were trying to parse ls. So i posted a link to a Q&A detailing why that's a bad idea and what you can/should do instead. What you do with that information is up to you. – cas Jan 20 '18 at 11:27
  • "(I'm not actually using ls / ll but I believe this redacted example displays the same issue I am having)" - Me – Jesse_b Jan 20 '18 at 18:24
  • 1
    @cas that wasn't witty at all it was just a fact. I removed the command from my actual code because it's proprietary so there is no purpose for it being in there. I needed another command that would produce multiple lines of output that also contained whitespace in each line and ls was my first thought. Since in my example I'm only pulling the top two lines of ls and simply echoing them I don't see that big of an issue with it. – Jesse_b Jan 24 '18 at 15:00
2

It seems to me that you're wanting to loop through your array, reading the elements into columns:

for ele in "${TEST_ARR[@]}"
do
  read -r col1 col2 col3 col4 col5 col6 col7 col8 TRASH <<< "$ele"
  echo -e "${col1}\n${col2}\n${col3}\n${col4}\n${col5}\n${col6}\n"
done
  • Thanks! I wasn't aware I could use read that way and had a method for setting all my variables with awk but it would not have been efficient. This is great! – Jesse_b Jan 20 '18 at 1:49
1

mapfile reads the contents of a file to an array, and if you use "${array[@]}" in a context like an assignment or <<< that takes only a single string, it concatenates all the array elements to a single string. A bit like "${array[*]}", except @ joins with spaces, and * with the first character of IFS.

Now, you said you "created a mapfile", but I don't think that's how the command name is supposed to be interpreted. It's more like that it "maps" a file to an array. (Except that it's a copy, not a two-way mapping like it might be in some languages.) The alternative name of readarray is probably more accurate.

  • I'm familiar with what an array is. Unfortunately I don't think this provides an answer to the question though. – Jesse_b Jan 20 '18 at 12:48

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.