Skip to content Skip to sidebar Skip to footer

Compare A .txt And .csv File And Need To Replace With Matching Name In .csv File To .txt

file1.txt [fields:WinSpc:defect] a=b b=c hello=hi [fields:ROCKET PROJECT:ticket] description=Descrtiption status=status [fields:PROJECT_Nexus:defect] title=summary priority=Prior

Solution 1:

A more scalable Awk logic can be done something as below.

Re-affirming the requirement for future readers, the .csv file has a field,replacement-of-field pair stored in multiple lines. For all those field in .csv the corresponding entries in .txt file should be replaced with replacement-of-field


1. replcement-of-field actually involves only the part after the dot

The below command does the job as intended.

awk 'FNR==NR{split($2,list,"."); replacement[$1]=list[2]; next} \
   {for (i in replacement){ if (match($0,i)) {gsub(i,replacement[i],$0); break} }}1 ' \
      FS="," file2.csv file1.txt

produces an output as OP needed,

[fields:winspc:defect]a=b
b=c
hello=hi
[fields:rocket_project:ticket]description=Descrtiption
status=status
[fields:project-nexus:defect]title=summary
priority=Priority_hello

Throwing in a bit of explanation,

  1. FNR==NR logic ensures the command after it within {} is run first for the .csv file. Note that .csv file is read with field-separator ,
  2. split($2,list,".");replacement[$1]=list[2]; next ensures that the second column of the file is split by . and a hash-map is created with index set to value to be replaced and the value as actual value to be replaced. This is done for all the lines in the .csv file
  3. Now on the .txt file, for each line is checked to see if the value to be replaced is present, if present it is replaced with the replacement value.

Solution 2:

A sed one-liner:

sed 's#,projects.#/#;s#.*#/fields/s/&/\;#' file2.csv | sed -f - file1.txt

How it works:

  1. Transform file2.csv into sedsubstitute commands. So the initial code sed 's#,projects.#/#;s#.*#/fields/s/&/\;#' file2.csv outputs:

    /fields/s/WinSpc/winspc/;
    /fields/s/ROCKET PROJECT/rocket_project/;
    /fields/s/PROJECT_Nexus/project-nexus/;
    
  2. Run the resulting substitute commands on file1.txt.

    Output:

    [fields:winspc:defect]a=b
    b=c
    hello=hi
    [fields:rocket_project:ticket]description=Descrtiption
    status=status
    [fields:project-nexus:defect]title=summary
    priority=Priority_hello
    

Solution 3:

Taken into consideration your comments, this looks an exercise to replace values that follows fields: in txt file, using replacement values from another file where the "fields" value is a kind of key.

Have a look in this approach:

$ readarray -t a < <(grep -e "\[fields:" a.txt |cut -d: -f2)$ for ((i=0;i<${#a[@]};i++));do a[i]=s/${a[i]}/$(grep -e "${a[i]}" b.txt |cut -d, -f2 |cut -d. -f2)/g\;;done$ sed -f <(echo"${a[@]}") a.txt

Output:

[fields:winspc:defect]a=b
b=c
hello=hi
[fields:rocket_project:ticket]description=Descrtiption
status=status
[fields:project-nexus:defect]title=summary
priority=Priority_hello

Explanation:

# grep the first file a.txt for all the fields: and keep the second part, i.e WinScp . Store all those findings in an array
$ readarray -t a < <(grep -e "\[fields:" a.txt |cut -d: -f2)
$ declare -p a #print the array to see what is inside#Bash Output: declare -a a=([0]="WinSpc" [1]="ROCKET PROJECT" [2]="PROJECT_Nexus")# Iterate through the array and with the stored value (i.e WinSpc) grep the second file # (b.txt in my test) and get the second field after comma. Store changes in the same array.
$ for ((i=0;i<${#a[@]};i++));do a[i]=s/${a[i]}/$(grep -e "${a[i]}" b.txt |cut -d, -f2 |cut -d. -f2)/g\;;done
$ declare -p a #print the array again. Now array looks like a sed pattern.# Bash Output: declare -a a=([0]="s/WinSpc/winspc/g;" [1]="s/ROCKET PROJECT/rocket_project/g;" [2]="s/PROJECT_Nexus/project-nexus/g;")# We can then apply all the sed patterns stored in array to replace values of text file (a.txt)
$ sed -f <(echo"${a[@]}") a.txt

Other solutions with AWK, etc may provide a more efficient code .

Post a Comment for "Compare A .txt And .csv File And Need To Replace With Matching Name In .csv File To .txt"