Используйте sed, чтобы заменить первые 8 и последние 4 канала в каждой строке файла - PullRequest
1 голос
/ 19 февраля 2010

Вот ситуация, у меня есть текстовый файл с разделителем канала, и одно из полей содержит символы канала.У меня уже есть скрипт Sed, который изменит его, чтобы разделить табуляцией, но проблема в том, что он ужасно медленный.Это заменит первое вхождение трубы 8 раз, затем заменит последнее вхождение трубы 4 раза.Я надеюсь, что есть более быстрый способ сделать то, что мне нужно.

Любые мысли будут оценены.Вот мой текущий скрипт sed:

sed 's/|\(.*\)/\t/;s/|\(.*\)/\t/;s/|\(.*\)/\t/;s/|\(.*\)/\t/;s/|\(.*\)/\t/;s/|\(.*\)/\t/;s/|\(.*\)/\t/;s/|\(.*\)/\t/;s/|\(.*\)/\t/;s/\(.*\)|/\t/;s/\(.*\)|/\t/;s/\(.*\)|/\t/;s/\(.*\)|/\t/' $1 > $1.tab

Спасибо,

-Dan

Ответы [ 4 ]

2 голосов
/ 19 февраля 2010
 sed 's/\([^|]\+\)|\([^|]\+\)|\([^|]\+\)|\([^|]\+\)|\([^|]\+\)|\([^|]\+\)|\([^|]\+\)|\([^|]\+\)|/\1\t\2\t\3\t\4\t\5\t\6\t\7\t\8\t/;s/|\([^|]\+\)|\([^|]\+\)|\([^|]\+\)|\([^|]\+\)$/\t\1\t\2\t\3\t\4/'

НТН

1 голос
/ 28 мая 2010

Я работал с Дэном, когда он нуждался в этом, но понял (как ghostdog74), что AWK был лучшим инструментом, но вот мой, возможно, неэффективный ответ.

awk -F"|" 'BEGIN{OFS="\t"}{for (i=10; i < NF-3; i++) $9=$9 "|" $i; print $1,$2,$3,$4,$5,$6,$7,$8,$9,$(NF-3),$(NF-2),$(NF-1),$(NF)}' $file > $file.tab

Что вы, ребята, думаете?

1 голос
/ 20 февраля 2010

Это несколько масштабируемо, но это все еще остроумно. Вы можете изменить «8» и «4», чтобы выбрать, какие диапазоны каналов вы хотите заменить, или изменить каналы или вкладки на другие символы.

В качестве однострочного:

sed 's/|/\n/8; h; s/.*\n//; x; s/\n.*/\t/; s/|/\t/g; G; s/\n//; s/\(\(|[^|]*\)\{4\}\)$/\n\1/; h; s/.*\n//; s/|/\t/g; x; s/\n.*//; G; s/\n//'

Здесь это вспыхнуло. Я перекомментировал это, так что за ним легко следовать.

sed '
s/|/\n/8     # split
h            # dup
s/.*\n//
# this is now the field which will retain the pipes 
# plus the fields at the end of the record
x            # swap
s/\n.*/\t/   # replace
s/|/\t/g
# this is now all the tab-delimited fields at the beginning of the record
G            # append
s/\n//
# this is now the full record with the first part completed
# the rest of the steps are similar to the steps above
s/\(\(|[^|]*\)\{4\}\)$/\n\1/    # split
h            # dup
s/.*\n//
s/|/\t/g     #replace
# this is now the last four fields that have been tab delimited
x            # swap
s/\n.*//
# this is the first eight fields plus the field with the retained pipes
G            # append
s/\n//
# now print the full record with everything done
'
0 голосов
/ 20 февраля 2010

Деннис прав, вы должны использовать квантификатор, чтобы указать, сколько раз в шаблоне вы хотите, чтобы действие было выполнено.

Посмотрите на ссылку ниже в разделе "Основные замены", так какчитается на сайте, чем здесь: http://www.readylines.com/sed-one-liners-examples

Надеюсь, что помогает.

...