Удалить пробелы и заменить символ пробелом - PullRequest
1 голос
/ 07 марта 2019

У меня есть файл с тысячами строк. Пример строки:

205.188.213.249:193.219. 43. 13:193.219. 62.126:   82   76:         12:       2868
193.219.168. 18:206.126.  6. 38: 62. 40.103.217:    4   82:         11:        701
193.219. 52.163:217. 44.206.181: 62. 40.103.217:   76   82:          9:        531
193.219. 74.113:195. 22.175.  2:193.219. 62.126:    0   76:         29:      10396
193.219. 32. 13:195. 34. 96.  3: 62. 40.103.217:    0   82:          1:        227

Мне нужно:
1) убрать пробелы между номерами IP-адресов;
2) изменить этот символ : на space

Это должно выглядеть так:

205.188.213.249 193.219.43.13 193.219.62.126 82 76 12 2868

Я пытаюсь с помощью этой команды: tr -d ' ' | tr ':' ' ' myfile, но не работает.

Ответы [ 4 ]

0 голосов
/ 07 марта 2019

Вы можете попробовать с помощью sed:

sed '
  :A
    s/\([^[:blank:]]*\)[[:blank:]]\(.*\.[^\.]*\)/\1\2/
    tA
  s/:\?[[:blank:]]\{1,\}\|:/ /g
' infile
0 голосов
/ 07 марта 2019

Попробуйте это:

awk -F: '{for (i=1;i<=NF;i++) if (split($i,tmp,".") == 4) gsub(/[[:space:]]/,"",$i); else {gsub(/^[[:space:]]+|[[:space:]]+$/,"",$i);gsub(/[[:space:]]+/,OFS,$i);}}1' myfile

Поставьте несколько строк и добавьте объяснение:

awk -F: '{                                             ## -F: assign : as separator
    for (i=1;i<=NF;i++) {                              ## iterate every field
        if (split($i,tmp,".") == 4) {                  ## If split with . yields four parts, then it is an ip.
            gsub(/[[:space:]]/,"",$i);                 ## Remove every space in the IP field.
        } else {                                       ## otherwise it is not an IP
            gsub(/^[[:space:]]+|[[:space:]]+$/,"",$i); ## replace the spaces at the beginning or ending of each fields. Equals trim in some languages.
            gsub(/[[:space:]]+/,OFS,$i);               ## Replace multiple places between with one space.
        }                                              
    }                                                  ## Below 1 is to print line
}1' myfile                                             

Это будет более совместимо, может работать и с TAB, и положение пробелов не ограничено.

0 голосов
/ 07 марта 2019

Использование Perl

 perl -lpe 's/\.\s+(?=\d+)/./g;s/:/ /g; s/\s+/ /g ' input_file

с заданными вами входами

$ cat edgaras.txt
205.188.213.249:193.219. 43. 13:193.219. 62.126:   82   76:         12:       2868
193.219.168. 18:206.126.  6. 38: 62. 40.103.217:    4   82:         11:        701
193.219. 52.163:217. 44.206.181: 62. 40.103.217:   76   82:          9:        531
193.219. 74.113:195. 22.175.  2:193.219. 62.126:    0   76:         29:      10396
193.219. 32. 13:195. 34. 96.  3: 62. 40.103.217:    0   82:          1:        227

$ perl -lpe 's/\.\s+(?=\d+)/./g;s/:/ /g; s/\s+/ /g ' edgaras.txt
205.188.213.249 193.219.43.13 193.219.62.126 82 76 12 2868
193.219.168.18 206.126.6.38 62.40.103.217 4 82 11 701
193.219.52.163 217.44.206.181 62.40.103.217 76 82 9 531
193.219.74.113 195.22.175.2 193.219.62.126 0 76 29 10396
193.219.32.13 195.34.96.3 62.40.103.217 0 82 1 227

$
0 голосов
/ 07 марта 2019

Не могли бы вы попробовать следующее (протестировано с предоставленным образцом и с GNU awk).

awk '{gsub(/:/," ");gsub(/\. +/,".");gsub(/ +/," ")} 1' Input_file

Объяснение: Использование здесь gsub для глобальной замены. 1-й глобально замещающий двоеточие пробелом, затем глобально заменяющий DOT пробелом. Наконец, глобально заменяя пространство (ы) одним пробелом. Затем, упомянув 1, дайте awk знать, чтобы напечатать отредактированную / нередактированную строку.

awk работает над методом регулярного выражения / условием, а затем действием. Если какое-либо регулярное выражение / условие имеет значение ИСТИНА, то будет выполнено действие, упомянутое рядом с ним. В этом случае я не упомянул никаких действий, поэтому по умолчанию будет напечатана текущая строка.

О gsub от человека: awk:

   gsub(r, s [, t])        For each substring matching the regular expression r in the string t, substitute the string s, and return the number of substitutions.  If t is not supplied, use $0.   An  &  in  the
                           replacement text is replaced with the text that was actually matched.  Use \& to get a literal &.  (This must be typed as "\\&"; see GAWK: Effective AWK Programming for a fuller dis-
                           cussion of the rules for &’s and backslashes in the replacement text of sub(), gsub(), and gensub().)


EDIT1: Добавление решения sed сейчас (проверено в GNU sed).

sed -E 's/:/ /g;s/\. +/\./g;s/ +/ /g' Input_file
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...