регулярное выражение awk / sed, извлекает столбец с разделителем

#regex #sed #awk

#регулярное выражение #sed #awk

Вопрос:

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

Существует ли какое-либо регулярное выражение, с помощью которого я могу правильно извлечь столбец name. Могу ли я в любом случае использовать sed для замены (или удаления) пространства в этом столбце, чтобы я мог легко удалить этот столбец?

Пример:

  1 2 name 3 4
 12 12 name1 name2 3 4
 12 12 name1 name2 name3 name4 3 4 
 3 4 name 3 4 
  


Результат, который я хочу получить, это:

 name 
name1_name2
name1_name2_name3_name4
name
  

Спасибо,

Амир,

Ответ №1:

Одним из решений с использованием awk является:

 cat foo | awk '{ for(i=3; i<=NF-3; i  ) { printf $i "_"; } printf $i "n";  }'
  

Здесь то же самое, используя sed:

 cat foo  | sed -e 's/^[0-9 ]*//g' -e 's/ [0-9 ]*$//g' -e 's/ /_/g'
  

Для ясности совместим с POSIX:

 cat foo  | sed -e 's/^[[:digit:][:space:]]*//g' -e 's/[[:space:]]*[[:digit:][:space:]]*$//g' -e 's/ /_/g'
  

Комментарии:

1. 1) Почему вы использовали каналы здесь? Sed и awk могут получить входной файл из аргументов.

2. 2) Почему вы добавляете new -e для всех этих мини-скриптов. Все это могло бы быть более компактным и простым для понимания.

3. @dmalikov 1) я не был уверен, был ли его вывод статическим файлом или нет. 2) это потоковый редактор, и решение заключается в многократном редактировании, порядок редактирования имеет значение…

Ответ №2:

 sed 's/^[0-9]  [0-9]  (.*) [0-9]  [0-9] $/1/;s/ /_/g'
  

Ответ №3:

другой способ awk без зацикливания

  awk 'BEGIN{OFS="_"}{$1=$2=$NF=$(NF-1)="";gsub(/__/,"")}1' yourFile
  

тест:

 kent$  cat t
 1 2 name 3 4
 12 12 name1 name2 3 4
 12 12 name1 name2 name3 name4 3 4 
 3 4 name 3 4 

kent$  awk 'BEGIN{OFS="_"}{$1=$2=$NF=$(NF-1)="";gsub(/__/,"")}1' t
name
name1_name2
name1_name2_name3_name4
name
  

Ответ №4:

Пара параметров Perl

 perl -lne  '/d  d  (. ) d  d / and do {($_ = $1) =~ s/ /_/g; print}'
perl -lape  'for (1..2) {shift @F; pop @F}; $_ = join "_", @F'