Score:3

bash script to compare fields of two files and replace columns

eg flag

I have two files.

File A:

newname,1,string
newname,2,string
newname,3,string
...
name,65500,string

File B;

oldname,1,string
oldname,2,string
oldname,3,string
...
oldname,65500,string

I need a bash script to change "oldname" in file B with "newname" in file A where their second column number match.

Score:7
jp flag

Assuming no duplicate second fields in file A, then with awk:

awk -F',' 'BEGIN{OFS=FS} NR==FNR{a[$2]=$1; next} ($2 in a ){$1=a[$2]}1' A B

Explanation:

  • -F',' will set the field separator to commas , to read the comma separated fields correctly.

  • BEGIN{OFS=FS} will set the output field separator OFS to the current field separator FS for output/result printing purposes ... a BEGIN block will execute first before the rest of the AWK script.

  • NR==FNR{a[$2]=$1; next} is a conditional NR==FNR which will evaluate to true as long as the file being processed is the first file of the two A and B by the order they are passed as arguments to the AWK script which, in the above case, is file A ... And an action {a[$2]=$1; next} where a[$2]=$1 will read the first field $1 in each line into an array element in the array a indexing it by the value of the second field $2 in the same line ... And next will skip to the next block when the condition is not true anymore i.e. it will keep processing the current block as long as its condition evaluates to true and will skip this block otherwise.

  • ($2 in a ){$1=a[$2]}1 is now processing the second file i.e. B where the second field $2 in each line is looked for in the indices of the array a with the condition ($2 in a ) and if it evaluates to true, which means the value is equal in both files for the second field in the current line, then the action $1=a[$2] will substitute the first field $1 in the current line with the element in the array a that it's index have just been found in the array a and the 1 will always evaluate to true which will print all the lines(modified and not modified) in the currently being processed file i.e. file B.

vn flag
Nice onliner. A nice description would be nice :)
Raffa avatar
jp flag
@PabloBianchi Done that ... Hopefully as nice as you expected :)
Score:1
bs flag
knu

The Unix way is with a few basic utilities:

join -t, -1 2 -2 2 -o 1.1,1.2,2.3 <(sort -t, -k2,2 A) <(sort -t, -k2,2 B)

See also:

  • man sort
  • man join
  • man bash (for the <() construct)
I sit in a Tesla and translated this thread with Ai:

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.