Обрезать пробелы внутри угловых скобок в седе

Я на самом деле решил это при составлении вопроса, но я думаю, что это может быть лучше, чем то, как я это сделал.

Я хотел урезать пробелы и большинство знаков препинания, кроме юридического URL-адреса (из сущностей rdf/n3), который появляется внутри <>s.

Пример исходного текста:
<this is a problem> <this_is_fine> "this is ok too" .<http://WeDontNeedToTouchThis.> <http:ThisContains"Quotes'ThatWillBreakThings> "This should be 'left alone'." .

Выходные данные должны преобразовывать пробелы в подчеркивания и обрезать кавычки и все, что не разрешено в url / iri.

<http://This is a "problem"> => <http://This_is_a_problem>

Это не сработало.
sed -e 's/\(<[^ ]*\) \(.*>\)/\1_\2/g' badDoc.n3 | headsed '/</,/>/{s/ /_/g}' badDoc.n3 | head

Мое возможное решение, которое, кажется, работает:
sed -e ':a;s/\(<[^> ]*\) \(.*>\)/\1_\2/g;ta' badDoc.n3 | sed -e ':b;s/\(<[:/%_a-zA-Z0-9.\-]*\)[^><:/%_a-zA-Z0-9.\-]\(.*>\)/\1\2/g;tb' > goodDoc.n3

Есть ли способ лучше?

1 ответ

Прежде всего, я бы сказал, что это интересная проблема. Это выглядит простой проблемой замещения, однако, если вдаваться в подробности, это не так просто, как я думал. Когда я искал решение, я скучаю по Vim!!!...:)

Я не знаю, если sed является обязательным для этого вопроса. Я бы сделал это с помощью awk:

awk '{t=$0;
        while (match(t,/<[^>]*>/,a)>0){
                m[++i]=a[0];n[i]=a[0];t=substr(t,RSTART+RLENGTH)
        }
        for(x in n){
                gsub(/[\x22\x27]/,"",n[x])
                gsub(/ /,"_",n[x])
                sub(m[x],n[x])
        }}1' file

протестируйте это немного с вашим примером:

kent$  cat file
<this is a problem> <this_is_fine> "this is ok too" . <http://WeDontNeedToTouchThis.> <http:ThisContains"Quotes'ThatWillBreakThings> "This should be 'left alone'." .

kent$  awk '{t=$0;
        while (match(t,/<[^>]*>/,a)>0){
                m[++i]=a[0];n[i]=a[0];t=substr(t,RSTART+RLENGTH)
        }
        for(x in n){
                gsub(/[\x22\x27]/,"",n[x])
                gsub(/ /,"_",n[x])
                sub(m[x],n[x])
        }}1' file
<this_is_a_problem> <this_is_fine> "this is ok too" . <http://WeDontNeedToTouchThis.> <http:ThisContainsQuotesThatWillBreakThings> "This should be 'left alone'." .

ну, на самом деле это не одна строка, посмотрите, есть ли другие более короткие решения от других.

Другие вопросы по тегам