Не ответ, просто чтобы показать более краткий идиоматический способ заполнения массива table[]
из ответа @konsolebox, как обсуждалось в соответствующих комментариях:
BEGIN {
split("a e b", old)
split("x ch o", new)
for (i in old)
table[old[i]] = new[i]
FS = OFS = ""
}
поэтому сопоставление старых и новых символов ясно показано тем, что символ в первом split() сопоставляется с символами под ним, а для любого другого сопоставления, которое вы хотите, вам просто нужно изменить строку (строки) в split(), а не изменять 26-кратные явные назначения для таблицы [].
Вы даже можете создать общий скрипт для сопоставления и просто передать старые и новые строки в качестве переменных:
BEGIN {
split(o, old)
split(n, new)
for (i in old)
table[old[i]] = new[i]
FS = OFS = ""
}
затем в оболочке что-то вроде этого:
old="a e b"
new="x ch o"
awk -v o="$old" -v b="$new" -f script.awk file
и вы можете защитить себя от собственных ошибок, заполняя строки, например:
BEGIN {
numOld = split(o, old)
numNew = split(n, new)
if (numOld != numNew) {
printf "ERROR: #old vals (%d) != #new vals (%d)\n", numOld, numNew | "cat>&1"
exit 1
}
for (i=1; i <= numOld; i++) {
if (old[i] in table) {
printf "ERROR: \"%s\" duplicated at position %d in old string\n", old[i], i | "cat>&2"
exit 1
}
if (newvals[new[i]]++) {
printf "WARNING: \"%s\" duplicated at position %d in new string\n", new[i], i | "cat>&2"
}
table[old[i]] = new[i]
}
}
Разве не было бы хорошо знать, если бы вы написали, что b отображается в x, а затем по ошибке написали, что b отображается в y? Вышеупомянутое действительно лучший способ сделать это, но, конечно, ваш выбор.
Вот одно полное решение, как обсуждалось в комментариях ниже.
BEGIN {
numOld = split("a e b", old)
numNew = split("x ch o", new)
if (numOld != numNew) {
printf "ERROR: #old vals (%d) != #new vals (%d)\n", numOld, numNew | "cat>&1"
exit 1
}
for (i=1; i <= numOld; i++) {
if (old[i] in table) {
printf "ERROR: \"%s\" duplicated at position %d in old string\n", old[i], i | "cat>&2"
exit 1
}
if (newvals[new[i]]++) {
printf "WARNING: \"%s\" duplicated at position %d in new string\n", new[i], i | "cat>&2"
}
map[old[i]] = new[i]
}
FS = OFS = ""
}
{
for (i = 1; i <= NF; ++i) {
if ($i in map) {
$i = map[$i]
}
}
print
}
Я переименовал массив table
в map
только потому, что iMHO лучше отражает назначение массива.
сохраните вышеуказанное в файле script.awk
и запустите его как awk -f script.awk inputfile
person
Ed Morton
schedule
17.08.2014