I have a text file as such:


The column 'Order' contain the name of the folder that I want to move to the corresponding folder (same row in the text file) which is shown in the 'Site_ID' column. This is an example for only one folder to be moved. In this example, I want to move the folder'besnard.sim@gmail.com-10132016-093523-554' to the folder 'AR-Slu'. The information contain in the table are the name of the folder but do not have path information of the folders. However, the two folders are in the same parent folder. Anyone would know how to do it?

1 Answer 1


For blank-separated values

(as in the initial version of your question)

(cd /parent/folder && tail -n +2 | xargs -L 1 mv --) < file

The tail is to skip the header.

With -L 1, xargs runs one mv command for each 1 line of its input with the words on that line passed as arguments to mv.

For xargs, words are blank delimited (whether it's all blanks or only space and tab depends on the xargs implementation), though xargs also recognises ", ' and \ as quoting operators that can be used to escape those blanks or each other.

You could also use a while read shell loop:

  cd /parent/folder || exit
  unset -v IFS
  read skip_header <&3
  while read src dst rest_ignored <&3; do
    mv -- "$src" "$dst" || ret=$?
  exit "$ret"
) 3< file

Again, for read and with the default value of $IFS (or after unset IFS), words are space or tab separated. \ can be used to escape those or itself or continue lines on the next physical line.

For CSV files

If the file is a CSV file (values separated by , and possibly surrounded by quotes), then you could run that loop in the ksh93 shell and use the -S option of it's read builtin for CSV parsing:

#! /bin/ksh93 -
  cd /parent/folder || exit
  read -S skip_header <&3
  while read -S src dst rest_ignored <&3; do
    mv -- "$src" "$dst" || ret=$?
  exit "$ret"
) 3< file

You can take off the -S option so it also works in other POSIX shells like bash which would work as long as CSV quoting is not used in the file.

Or you could use a CSV parsing module in perl or other scripting language:

(cd /parent/folder && perl -C -MText::CSV -e '
  $c = Text::CSV->new;
  $ret = 0;
  $c->getline(STDIN); # skip header
  while (($src, $dst) = @{$c->getline(STDIN)}) {
    system "mv", "--", $src, $dst;
    $ret = 1 if $?;
  exit $ret;') < file
  • I guess there is a need to specify the path of the two directories somewhere no?
    – SimonB
    Oct 20, 2016 at 13:47
  • Just did the edit.
    – SimonB
    Oct 20, 2016 at 13:58
  • @SimonB, see edit. Oct 20, 2016 at 14:04
  • I have this error message: 'xargs: 1: No such file or directory'. If I do 'tail -n +2 file', the output looks like 'besnard.sim@gmail.com-10132016-093523-554,AR-Slu' Any idea what I am doing wrong?
    – SimonB
    Oct 20, 2016 at 14:21
  • @SimonB. I overlooked the fact that -l was not portable (no longer standard) (and with GNU xargs, one needs -l1 instead of -l 1). -L is the standard (Unix, not POSIX) equivalent. What operating system are you on? Oct 20, 2016 at 14:43

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.