Ответ 1
да, FS может быть многосимвольным. см. ниже тест с вашим примером:
kent$ echo '"School","College","City"'|awk -F'","|^"|"$' '{for(i=1;i<=NF;i++){if($i)print $i}}'
School
College
City
Могу ли я использовать разделитель полей, состоящий из нескольких символов? Как будто я хочу разделить слова, содержащие цитаты и запятые между ними, а именно:
"Школа", "Колледж", "Город"
Поэтому здесь я хочу настроить FS как ",". Но я получаю забавные результаты, когда я так определяю свои FS. Вот фрагмент моего кода.
awk -F\",\" '
{
for(i=1;i<=NF;i++)
{
if($i~"[a-z0-9],[a-z0-9]")
print $i
}
}' OFS=\",\" $*
да, FS может быть многосимвольным. см. ниже тест с вашим примером:
kent$ echo '"School","College","City"'|awk -F'","|^"|"$' '{for(i=1;i<=NF;i++){if($i)print $i}}'
School
College
City
Здесь говорится, что полевой разделитель не ограничивается только несколькими символами, но может быть полномасштабным регулярным выражением.
To wit: Это удаляет заголовок и окружающие теги из 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 доллара. Это действительно очень эффективно, потому что это означает, что вы можете использовать не только фиксированные шаблоны с несколькими символами, но и полную силу регулярных выражений, а также в своем разделителе полей.
Пытаться
awk 'BEGIN{FS="[|,:]"}{print $1}' youFile
С 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
Да, вы можете использовать несколько символов для аргумента -F
потому что это значение может быть регулярным выражением. Например, вы можете делать такие вещи, как:
echo "hello:::my:::friend" | gawk -F':::' '{print $3}'
который вернет friend
.
Поддержка regexp в качестве аргумента для -F
верна для nawk
и gawk
(GNU awk), оригинальный awk
не поддерживает его. В Solaris это различие важно, в Linux это не важно, потому что awk
- это действительно ссылка на gawk
. Поэтому я бы сказал, что лучше использовать awk как gawk
потому что тогда он будет работать на разных платформах.