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
.csv
file has afield,replacement-of-field
pair stored in multiple lines. For all thosefield
in.csv
the corresponding entries in.txt
file 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==NR
logic ensures the command after it within{}
is run first for the.csv
file. Note that.csv
file is read with field-separator,
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- 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:
Transform file2.csv into
sed
substitute commands. So the initial codesed 's#,projects.#/#;s#.*#/fields/s/&/\;#' file2.csv
outputs:/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.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"