So I have two language files, english and french. They are in this format:


An example in English would be:

ui.title=My Title

And in French:

ui.title=Mon Titre

So I need a script that reads the language files and finds the differences. So say that the English file had keys:


But French only had

ui.title=Mon Titre

After running the script, it should output a file french.changes containing ui.close=Close. So this way, I can send the file off to my translators and they can translate it.

When I get it back, I can simply run cat french.changes >> french; sort -o Language_fr_FR.properties, to merge the changes.

I also need a method of sorting the language files by the key not the whole line.

I looked into diff but not sure how to use it correctly. I have been using Linux for quite a while but not so up to speed on fancy scripting :)

Thanks for any help!

  • Are all key=translation entries on separate lines? Apart from the missing lines, are all entries in the same order? Is the order of the lines of importance or could they be rearranged? – Fiximan Aug 15 '15 at 19:03
  • 1. I changed my mind, I want the output of the changes file to be like ui.close=Close rather than ui.close= so that people know what to translate. 2. Yes, they are all on separate lines. 3. The order of the lines in the .changes file doesn't have to be sorted, but the one after being merged back after translation should be. – Chris Smith Aug 15 '15 at 19:10

You could use:

grep -v -f <(sed -r 's/([^=]*).*$/\1/' fr.i18n.txt) en.i18n.txt

Which filters all keys from fr.i18n.txt from en.i18n.txt.


$ cat > en.i18n.txt
$ cat > fr.i18n.txt
$ grep -v -f <(sed -r 's/([^=]*).*$/\1/' fr.i18n.txt) en.i18n.txt
$ FINISHED="$(grep -v -f <(sed -r 's/([^=]*).*$/\1/' fr.i18n.txt) en.i18n.txt)"
$ echo "$FINISHED"

@don_crissti also correctly pointed out, that in this case the filterlist can also easily by generated with cuttin the 1st field using the delimiter '=':

grep -v -f <(cut -d= -f1 fr.i18n.txt) eng.i18n.txt

|improve this answer|||||

The following takes two files, eng and fr, sorts them on the key, and "joins" them on the key, showing only any missing entries from file 1 (eng).

join -t= -v1 <(sort -t= -k 1,1 eng) <(sort -t= -k 1,1 fr)

So the sort on key you want is eg:

sort -t= -k 1,1 eng
|improve this answer|||||
  • Same thing here, a messed up, I want the output of the changes file to be like ui.close=Close rather than ui.close= so that people know what to translate. Sorry for the inconvenience. – Chris Smith Aug 15 '15 at 19:13
  • Would this work with more parts of the key? I see 1.1, 2.2 etc and not sure if that is limiting it to only *.* and not allowing for a key of x.y.z.a.b.c=Hello! – Chris Smith Aug 15 '15 at 19:23
  • 1.2 refers to field 2 of file 1, where the fields were split on "=", so the form of the key is not important. – meuh Aug 15 '15 at 19:27
  • 1
    join -v1 -t= <(sort eng) <(sort fr) is enough for english field data – Costas Aug 15 '15 at 19:48
  • @Costas great simplification, thanks. my notes on join from 10+ years ago need a refresh. I still needed to sort on the key only though, else join complains with my example data with keys of different lengths. – meuh Aug 15 '15 at 20:17

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.