0

I want to rename directories based on matching information from columns of the CSV file.

For example, the columns in the csv file with repeated some rows looks like this:

1111,ABC1
1111,ABC1
2222,DFG2
3333,FEG1
3333,FEG1
4444,TTG2  

The existing directories are with following names:

1111 2222 3333 4444 

I want to rename these directories by matching with column 1 and appending the corresponding column 2 information along with it.

I read the columns as follows:

col1_id=$(awk -F "\"*,\"*" '{print $1}' "$somefile" | sed 1d | awk '!a[$0]++')
col2_id=$(awk -F "\"*,\"*" '{print $2}' "$somefile" | sed 1d | awk '!a[$0]++')

I tried to map the columns and append as follows:

cnt=${#col1_id[@]}
for ((i=0;i<cnt;i++)); 
do
    mv "{$col1_id[i]}" "${col1_id[i]}_${col2_id[i]}"
done

However, I am not getting the desired output. My output directories should be with names.

1111_ABC1 2222_DFG2 3333_FEG1 4444_TTG2
6
  • What is the desired output? Sep 19 '21 at 22:38
  • Edited the post.
    – botloggy
    Sep 19 '21 at 22:43
  • Can you please elaborate a bit?
    – botloggy
    Sep 20 '21 at 2:42
  • Sure, I have edited the question based on your comment
    – botloggy
    Sep 20 '21 at 13:07
  • You say you have a CSV but your sample input is space-separated, not comma-separated, please edit your question to make sure the text and example reflect the same information.
    – Ed Morton
    Sep 20 '21 at 13:11
1

With GNU tools, you could do something like:

<file.csv uniq | gawk -F, '{printf "%s\0%s_%s\0", $1, $1, $2}' |
  xargs -r0n2 mv -T --

Where gawk prints 1111 and 1111_ABC1 NUL-delimited records for each each 1111,ABC1 line of input, and xargs takes 2 of them at a time to pass to mv -T --.

That assumes the duplicated lines are adjacent. If not, use sort -u instead of uniq or do the deduplicating in gawk:

<file.csv gawk -F, '!seen[$1]++ {printf "%s\0%s_%s\0", $1, $1, $2}' |
  xargs -r0n2 mv -T --

(here skipping the lines for which the first field has already been seen).

1
  • This is magic!!
    – botloggy
    Sep 20 '21 at 16:39
1

It sounds like you want to do something like this (untested):

#!/usr/bin/env bash

declare -A map
while IFS=, read -r old new rest_if_any_ignored; do
    map["$old"]="$new"
done < file

for old in *; do
    if [[ -n "${map[$old]}" ]]; then
        new="${map[$old]}"
        mv -- "$old" "${old}_${new}"
    fi
done
2
  • Can you please explain a bit more about this solution?
    – botloggy
    Nov 2 '21 at 20:25
  • I'm sorry but it's been over a year, I'm not going to revisit it now.
    – Ed Morton
    Nov 2 '21 at 20:55

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.