1

I have two files, each with data arranged in two columns. Columns are separated by a semicolon. The first file (11_19.txt) includes more lines and the second file(12_19.txt) is to update the first file. Each line has an id in the first part, so the script should update the first file with the data from the second file if it finds a line with the same id in the both files.

Lets say that first file is like this :

$ cat 11_19.txt
id=123;112233
id=456;445566
id=789;778899
id=000;000000

and the second file is like this :

$ cat 12_19.txt
id=123;123123
id=000;999999

Expected outcome of script :

$ ./script.sh 11_19 12_19
11_19
id=123;123123
id=456;445566
id=789;778899
id=000;999999

I tried turning parts of csv into an array but can't make it work.

id=($(cut -f1 -d, $2))
info=($(cut -f2 -d, $2))

for id in ${id[@]}; do
    if grep "$id" $1; then
        sed -E s/id="$id";.*/id="$id";$info"/ $1>$1
    else
        :
    fi
done

Secondly, I want to use the second file to change the values of a different file with a different extension, lets say an html file, and add the second value in the second file where the id matches in the html file.

<!DOCTYPE html>
<html>
<body>
...
<p1 id=123></p1>

Expected output:

<!DOCTYPE html>
<html>
<body>
...
<p1 id=123>123123</p1>
  • 2
    join would work if the files are appropriately sorted - aside from the field separator, this is essentially the same as updating one file based on values in another with AWK i.e. something like awk -F';' 'BEGIN{OFS=FS} NR==FNR{a[$1] = $2; next} $1 in a {$2 = a[$1]} {print}' 12_19.txt 11_19.txt – steeldriver Dec 8 '19 at 19:52
  • @steeldriver, what if I want to use the second file to update another file that isn't similarly formatted. Let's say this time I wanted to add the value where I find the same id. (so change any '<g id="123">' in new_file1 to '<g id="123" value="123123">' according to the values in the file2? – arthionne Dec 8 '19 at 20:53
  • @arthionne please edit your question to include all your requirements - or ask a separate question if they are substantively different – steeldriver Dec 8 '19 at 22:15
  • My first impulse is to read the file 11_19 into an associative array, then update the array from the entries in 12_19, then join the key-vallue pairs with a semicolon and write them out. But that only works in Bash. Is Bash your shell, or does it need to work with the POSIX sh command, too? Alternatively, I would consider implementing the same idea in AWK, which should be available from your shell. Is it? Speaking of associative arrays: Is the order of the entries in the script's output important to you? – Thomas Blankenhorn Dec 8 '19 at 23:01
  • @ThomasBlankenhorn, yes I am using bash and yes the order of the file should not be changed, just the value should be added. – arthionne Dec 8 '19 at 23:19
2

[Edit: I used data1 for OP's file 11_19.txt and data2 for OP's file 12_19.txt]

Note: as shown data1 and data2 need to be sorted on their respective first column, prior to executing the JOIN on first column.

$ cat data1
id=123;112233
id=456;445566
id=789;778899
id=000;000000

$ cat data2
id=123;123123
id=000;999999

Then issue either:

$ sed -E 's/\;.*\;/;/' <(join -a1 -j 1 -t";" <(sort data1) <(sort data2))
id=000;999999
id=123;123123
id=456;445566
id=789;778899

or the equivalent (in result):

$ join -a1 -j 1 -t";" <(sort data1) <(sort data2) | sed -E 's/\;.*\;/;/'
id=000;999999
id=123;123123
id=456;445566
id=789;778899

man join, man sed and info sed in terminal will give you the meaning of the various options used in the above one-liners.

|improve this answer|||||
1

Simple bash script:

$ cat script.sh
!/bin/bash

file1=$1
file2=$2

while IFS=';' read a b
do
    r="$b"
    while IFS=';' read c d
    do
        if [ "$a" == "$c" ]
        then
            r="$d"
        fi
    done < $file2
    printf "%s;%s\n" $a $r
done < $file1

$ ./script.sh 11_19 12_19
id=123;123123
id=456;445566
id=789;778899
id=000;999999
$

Note - There is no error checking in the script and it does not overwrite the original file.

|improve this answer|||||

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.