Самый эффективный способ gsub-строк в awk, где строки приходят из отдельного файла - PullRequest
0 голосов
/ 22 сентября 2019

У меня есть файл с разделителями табуляции под названием cities, который выглядит следующим образом:

Washington Washington N 3322 +Geo+Cap+US
Munich  München  N 3842  +Geo+DE
Paris Paris N 4948  +Geo+Cap+FR

У меня есть текстовый файл с именем countries.txt, который выглядит следующим образом:

US
DE
IT

Я читаю этот файл в переменную Bash и отправляю его в программу awk следующим образом:

#!/usr/bin/env bash

countrylist=$(<countries.txt)
awk -v countrylist="$countrylist" -f countries.awk cities

И у меня есть файл awk, который должен разбить переменную countrylist на массив, а затем обработатьфайлы городов так, что мы заменяем "+" VALUE на "" в $ 5, только если VALUE находится в массиве стран.

{
  FS = "\t"; OFS = "\t";
  split(countrylist, countries, /\n/)

  # now gsub efficiently every country in $5
  # but only if it's in the array
  # i.e. replace "+US" with "" but not 
  # "+FR"
}

Я застрял в этом последнем бите, потому что я не знаюкак проверить, имеет ли $5 значение из массива countries и удалить его только тогда.

Заранее большое спасибо!

[Edit]

Theвывод должен быть разделен табуляцией:

Washington  Washington  N   3322    +Geo+Cap
Munich  München N   3842    +Geo
Paris   Paris   N   4948    +Geo+Cap+FR

Ответы [ 2 ]

2 голосов
/ 22 сентября 2019

Не могли бы вы попробовать следующее, если я правильно понял ваше требование.

awk 'FNR==NR{a[$0]=$0;next} {for(i in a){if(index($5,a[i])){gsub(a[i],"",$5)}}} 1'  countries.txt  cities

Форма кода не с одним вкладышем выглядит следующим образом (вы можете установить FS и OFS на \t в случае, если ваш Input_file разделен символом TAB):

awk '
FNR==NR{
  a[$0]=$0
  next
}
{
  for(i in a){
    if(index($5,a[i])){
      gsub(a[i],"",$5)
    }
  }
}
1
'  countries.txt  cities

Вывод будет следующим:

Washington Washington N 3322 +Geo+Cap+
Munich München N 3842 +Geo+
Paris Paris N 4948  +Geo+Cap+FR
0 голосов
/ 22 сентября 2019

Это awk способ сделать это:

$ awk '
BEGIN {
    FS=OFS="\t"                # delimiters
}
NR==FNR {                      # process countries file
    countries[$0]              # hash the countries to an array
    next                       # skip to next citi while there are cities left
}
{
    n=split($5,city,"+")       # split the 5th colby +
    if(city[n] in countries)   # search the last part in countries
        sub(city[n] "$","",$5) # if found, replace in the 5th
}1' countries cities           # output and mind the order of files

Вывод (с фактическими вкладками в данных):

Washington      Washington      N       3322    +Geo+Cap+
Munich  München N       3842    +Geo+
Paris   Paris   N       4948    +Geo+Cap+FR
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...