#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'