I have used the info from another question on Stack Exchange to allow me to rename files using the info in a csv file. This line allows me to rename all files from the names in column 1, to the names in column 2.

while IFS=, read -r -a arr; do mv "${arr[@]}"; done <$spreadsheet 

However, it attempts to compare the info in the top row. I would like to be able to include some code which allows me to skip rows. It would also be nice to gain a better understanding of how the above line of code works. I would have thought it would include some info about columns (ie. A and B)


Try this:

tail -n +2 $spreadsheet | while IFS=, read -r -a arr; do mv "${arr[@]}"; done

The tail command prints only the last lines of a file. With the "-n +2", it prints all the last lines of the file starting at the second.

More on the while loop. The while loops runs the mv command as long as there are new lines available. It does that by using the condition of the while loop:

IFS=, read -r -a arr

What the above does is read one line into an array named arr, where the fields separator (IFS) is a comma. The -r option likely is not needed.

Then, when running the mv command, "${arr[@]}" is converted to the list of fields where each field is separated by double quotes. In your case, there are only two fields per line, so its expanded just to the two fields. The "${arr[@]}" is a special convention used by bash for Arrays, as explained in the manual:

   Any element of an array may be referenced using ${name[subscript]}.  The braces are
   required  to  avoid conflicts with pathname expansion.  If subscript is @ or *, the
   word expands to all members of name.  These subscripts differ only  when  the  word
   appears  within double quotes.  If the word is double-quoted, ${name[*]} expands to
   a single word with the value of each array member separated by the first  character
   of the IFS special variable, and ${name[@]} expands each element of name to a sepa-
   rate word.  When there are no array members, ${name[@]} expands to nothing.  If the
   double-quoted  expansion occurs within a word, the expansion of the first parameter
   is joined with the beginning part of the original word, and the  expansion  of  the
   last  parameter  is joined with the last part of the original word.  This is analo-
   gous to the expansion of the special parameters * and  @  (see  Special  Parameters
   above).   ${#name[subscript]} expands to the length of ${name[subscript]}.  If sub-
   script is * or @, the expansion is the number of elements in the array.   Referenc-
   ing  an  array  variable  without  a subscript is equivalent to referencing element
  • works a dream. Does anyone know what the "arr" bit refers to/does? I would mind understanding how this line works a little better than I do. – neilH Oct 15 '15 at 15:59
  • Updated my answer, if that helps. – Brian Oct 15 '15 at 17:55
  • Brilliant, thanks for going the extra mile Brian, top answer – neilH Oct 16 '15 at 10:58

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.