Replacement by dictionary possible with AWK or Sed? [closed]

橙三吉。 提交于 2019-12-01 13:39:18

问题


You have a dictionary, Dictionary.txt, and an input file, inFile.txt. The dictionary tells you about possible translations. The solution to a similar problem in unix shell: replace by dictionary seems to hardcode things here that I cannot fully understand. You can come up with better replacement technique than dictionary but AWK/Sed script should be able to read in multiple files, in the simplest case only one dictionary file and one infile.

How to replace elegantly by dictionary with AWK or Sed?


Example

Dictionary.txt

1 one
2 two 
3 three
four fyra
five fem

inFile.txt

one 1 hello hallo 2 three hallo five five

Output from the Command, we are after for the command like awk/sed {} Dictionary.txt inFile.txt

one one hello hallo two three hallo fem fem

AWK example where specifically selected the replacements but one-one replacements not working.

awk 'BEGIN {
 lvl[1] = "one"
 lvl[2] = "two"
 lvl[3] = "three"
 # TODO: this does not work 
 # lvl[four] = "fyra"
 # lvl[five] = "fem"
 # lvl[one] = "one"
 # lvl["hello"] = "hello"
 # lvl[hallo] = "hallo"
 # lvl[three] = "three"
 }
NR == FNR {
  evt[$1] = $2; next
  }
{
   print $1, evt[$2], $3, $4, evt[$5], $6, $7, evt[$8], evt[$9]
   #TODO: this dos not work, eg. one-one mapping   
   #   print evt[$1], evt[$2], evt[$3], evt[$4], evt[$5], evt[$6], evt[$7], evt[$8], evt[$9]
  }' dictionary.txt infile.txt

回答1:


$ awk 'NR==FNR{map[$1]=$2;next} { for (i=1;i<=NF;i++) $i=($i in map ? map[$i] : $i) } 1' fileA fileB
one one hello hallo two three hallo fem fem

Note that it will compress any chains of contiguous white space to a single blank char. Tell us if that is an issue.




回答2:


if you have gnu sed, it supports script-file with -f:

`-f SCRIPT-FILE'
`--file=SCRIPT-FILE'
     Add the commands contained in the file SCRIPT-FILE to the set of
     commands to be run while processing the input.

you could write your substitutions in "c.sed" for example, then

sed -f c.sed file

example c.sed:

s/1/one/g
s/2/two/g
...

EDIT

just now you didn't tag the question with awk, sure, the awk one-liner would be simpler: (with your example)

awk '$1=$2' file

test:

kent$  echo "1 one
2 two 
3 three
four fyra
five fem"|awk '$1=$2'
one one
two two
three three
fyra fyra
fem fem



回答3:


EDIT

This answers the original post. doesn't answer the multiple times edited and restructured question... on top of that I get a -1 from the OP who asked this question... Damn!

Yes, much simpler in awk :

This will print both column as the value for the second column :

awk '{print $2, $2}' file

If you want to flip first with second column:

awk '{print $2, $1}' file



回答4:


If ReplaceLeftWithRight_where_you_do_not_replace_things.txt contains pairs of string replacements, where any occurrence of the text in the first column should be replaced by the second column,

1 one
2 two 
3 three
four fyra
five fem

then this can trivially be expressed as a sed script.

s/1/one/g
s/2/two/g
s/3/three/g
s/four/fyra/g
s/five/fem/g

and you can trivially use sed to create this sed script:

sed 's%.*%s/&/g%;s% %/%' ReplaceLeftWithRight_where_you_do_not_replace_things.txt

then pass the output of that to a second instance of sed:

sed 's%.*%s/&/%;s% %/%' ReplaceLeftWithRight_where_you_do_not_replace_things.txt |
sed -f - someFile_Where_You_Replace_Things.txt

to replace all the matches in the file someFile_Where_You_Replace_Things.txt and have the output printed to standard output.

Sadly, not all sed dialects support the -f - option to read a script from standard input, but this should work at least on most Linuxes.

Sorry if I misunderstood your problem statement.



来源:https://stackoverflow.com/questions/18600278/replacement-by-dictionary-possible-with-awk-or-sed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!