Compare A .txt And .csv File And Need To Replace With Matching Name In .csv File To .txt
Solution 1:
A more scalable Awk logic can be done something as below.
Re-affirming the requirement for future readers, the
.csvfile has afield,replacement-of-fieldpair stored in multiple lines. For all thosefieldin.csvthe corresponding entries in.txtfile should be replaced withreplacement-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,
FNR==NRlogic ensures the command after it within{}is run first for the.csvfile. Note that.csvfile is read with field-separator,split($2,list,".");replacement[$1]=list[2]; nextensures 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.csvfile- Now on the
.txtfile, 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:
Transform file2.csv into
sedsubstitute commands. So the initial codesed 's#,projects.#/#;s#.*#/fields/s/&/\;#' file2.csvoutputs:/fields/s/WinSpc/winspc/; /fields/s/ROCKET PROJECT/rocket_project/; /fields/s/PROJECT_Nexus/project-nexus/;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.txtOutput:
[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"