Может ли разделитель полей в awk включать несколько символов? - PullRequest
14 голосов
/ 24 ноября 2011

Можно ли использовать разделитель полей, состоящий из нескольких символов? Как я хочу разделить слова, которые содержат кавычки и запятые между ними, а именно.

"Школа", "Колледж", "Город"

Итак, я хочу, чтобы моя FS была ",". Но я получаю забавные результаты, когда я определяю свою FS так. Вот фрагмент моего кода.

awk -F\",\" '
{
for(i=1;i<=NF;i++)
  {
    if($i~"[a-z0-9],[a-z0-9]") 
    print $i
  }
}' OFS=\",\"  $* 

Ответы [ 5 ]

17 голосов
/ 24 ноября 2011

да, FS может быть мультисимвольным. см. приведенный ниже тест на вашем примере:

kent$  echo '"School","College","City"'|awk -F'","|^"|"$' '{for(i=1;i<=NF;i++){if($i)print $i}}'
School
College
City
8 голосов
/ 08 февраля 2012

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

То есть: это удаляет заголовок и окружающие теги изфрагмент XML.Обратите внимание, что теги правильные, но разные.

bash-3.2$ more xml_example 
<?xml version="1.0" encoding="UTF-8"?>
<urlset
xmlns="http://www.google.com/schemas/sitemap/0.84"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.google.com/schemas/sitemap/0.84
                  http://www.google.com/schemas/sitemap/0.84/sitemap.xsd">
<url>
<loc>http://www.foo.com/about.html</loc>
<lastmod>2006-05-15T13:43:37Z</lastmod>
<priority>0.5000</priority>
</url>
<url>
<loc>http://www.foo.com/articles/articles.html</loc>
<lastmod>2006-06-20T23:03:36Z</lastmod>
<priority>0.5000</priority>
</url>

Теперь мы применяем скрипт awk для распечатки среднего поля, используя регулярное выражение в качестве разделителя полей:

bash-3.2$ awk -F"<(/?)[a-z]+>" '{print $2}' <xml_example




http://www.foo.com/about.html
2006-05-15T13:43:37Z
0.5000


http://www.foo.com/articles/articles.html
2006-06-20T23:03:36Z
0.5000

bash-3.2$

Пустые строки, из которых тег был единственнымчто-то в этой строке, так что нет 2 $ для печати.На самом деле это действительно мощно, потому что это означает, что вы можете использовать не только фиксированные шаблоны с несколькими символами, но и всю мощь регулярных выражений, а также разделитель полей.

4 голосов
/ 02 апреля 2013

Попробуйте

awk 'BEGIN{FS="[|,:]"}{print $1}' youFile
2 голосов
/ 24 ноября 2011

С GNU awk 4 вы можете легко анализировать даже * CSV * s со встроенными разделителями и кавычками:

% cat infile 
"School",College: "My College","City, I"

% awk '{    
  for (i = 0; ++i <= NF;)
    print i, substr($i, 1, 1) == "\042" ?
      substr($i, 2, length($i) - 2) : $i
  }' FPAT='([^,]+)|(\"[^\"]+\")' infile  
1 School
2 College: "My College"
3 City, I
1 голос
/ 30 августа 2013

Да, вы можете использовать несколько символов для аргумента -F, потому что это значение может быть регулярным выражением.Например, вы можете сделать что-то вроде:

echo "hello:::my:::friend" | gawk -F':::' '{print $3}'

, который вернет friend.

Поддержка регулярного выражения в качестве аргумента -F истинна для nawk и gawk (GNU awk), оригинал awk не поддерживает его.В Solaris это различие важно, в Linux оно не важно, потому что awk фактически является ссылкой на gawk.Поэтому я бы сказал, что лучше всего вызывать awk как gawk, потому что тогда он будет работать на разных платформах.

...