Принятие Вас говорит о Linux, iptables
имеет a mangle
таблица, которая может сделать все виды сумасшедших вещей к исходящему трафику TCP. iptables
Функции NAT могли бы помочь также, потому что это действительно кажется, что Вы хотите сделать "перевод адреса порта" или "ручной NAT".
Это должно сделать это:
sed -e 's/\([^,:]*\), *\([^:]*\)/\2, \1/;s/:[^:]*$//' student.txt
Первый оператор (разделенный ;
) поиски Фамилии, разграниченной пространством запятой и Именем, разграниченным двоеточием, и, подкачивают их, с помощью разделителя пространства запятой. Второй оператор ищет последнее двоеточие и удаляет это и что-либо в конец строки. Как кто-то упомянул, это могло быть обработано awk.
awk -F: 'BEGIN{OFS=":"}{split($1,N,", ");$1=N[2]", "N[1];NF=2;print}' student.txt
Q.E.D
Для sed
Вы захотите три обратных ссылки. Первое, разграниченное запятой и вторыми двумя, разграниченными двоеточием
sed 's/^\([^,]*\), \([^:]*\): \([^:]*\).*$/\2, \1: \3/' students.txt
Однако при контакте с разделителем и полями, awk
действительно инструмент для использования, потому что можно указать разделителя полей, который может быть regex. В этом случае наш разделитель полей является или запятой или двоеточием, сопровождаемым пространством.
awk -F'[,:] ' '{printf("%s, %s: %s\n",$2,$1,$3)}' students.txt
Хотя, следующее решение неуниверсально, однако если формат данных остается тем же. Затем следующее решение будет работать также;
sed -r 's/^([A-Za-z]+), ([A-Za-z]+): (([0-9]{2}\.){2}[0-9]{4}): .*$/\2,\1: \3/' students.txt
Вместо sed, это могло бы быть более легкое использование awk с разделителем полей ':', и просто распечатайте первые два поля.
sed
потому что это - домашняя работа, и они вынуждены выполнить в нем sed
:)
– sakisk
28.03.2011, 11:01
Если Вы не должны использовать sed
, используйте cut
команда.
cut -d : -N 1-2 students.txt
добился бы цели
Проблемы с вашей командой,
sed -e 's/\(.*\),(.*\)/\2/\1/'
это
Скобки не сбалансированы, так как вы забыли обратную косую черту перед второй открывающей скобкой.
Текст замены содержит un -escaped /
.
Даже с указанным выше исправлением он не будет делать то, что, я думаю, вам хотелось бы.
В синтаксисе -исправлена команда:
sed -e 's/\(.*\),\(.*\)/\2\/\1/'
При заданных данных это даст
John: 15.01.1986: MSc IT /Smith
Susan: 04.05.1987: MSc IT /Taylor
Steve: 19.04.1986: MSc MIT /Thomas
Joseph: 01.12.1987: MSc IT /Sennick
т. е. он возьмет имя и остальную часть строки после запятой и поменяет их местами с /
в -между ними.
Насколько я понимаю, вы пытались
sed -e 's/\(.*\), \([^:]*\):/\2,\1:/'
который производит
John,Smith: 15.01.1986: MSc IT
Susan,Taylor: 04.05.1987: MSc IT
Steve,Thomas: 19.04.1986: MSc MIT
Joseph,Sennick: 01.12.1987: MSc IT
Это ожидаемый результат, за исключением того, что он по-прежнему содержит степень в конце. Чтобы удалить степень, мы можем сделать вторую замену:
sed -e 's/\(.*\), \([^:]*\):/\2,\1:/' -e 's/:[^:*]*//'
Это дает вам
John,Smith: MSc IT
Susan,Taylor: MSc IT
Steve,Thomas: MSc MIT
Joseph,Sennick: MSc IT
Есть несколько других способов сделать это. С помощью awk
, например:
$ awk -F: -v OFS=: '{ d=$2; split($1,a,", "); $0=""; $1=a[2] "," a[1]; $2=d; print }' file
John,Smith: 15.01.1986
Susan,Taylor: 04.05.1987
Steve,Thomas: 19.04.1986
Joseph,Sennick: 01.12.1987
Здесь мы переписываем каждую строку с нуля, используя биты, извлеченные из исходной строки. Имя строится из битов, которые мы получаем путем явного разделения поля имени на запятую -, за которой следует -и -пробел.