Как с помощью AWK извлечь определенные столбцы из одного CSV-файла в другой?

Используйте mimeopen -dдля установки приложения по умолчанию:

mimeopen -d image.png

пример вывода:

Please choose a default application for files of type image/png
1) ImageMagick (color depth=q16)  (display-im6.q16)
2) GNU Image Manipulation Program  (gimp)
3) Feh (feh)

Выберите приложение по умолчанию, в следующий раз вы сможете использовать:

mimeopen image.png

или:

xdg-open image.png
1
26.02.2021, 22:34
3 ответа

Каждый раз, когда у вас есть пары тег=значение в ваших данных, я считаю, что лучше всего сначала создать массив для хранения этого сопоставления(tag2val[]ниже ), а затем вы можете ссылаться на все значения по их тегам (aka имена или ключи ).

Использование любого awk в любой оболочке на всех компьютерах Unix:

$ cat tst.awk
BEGIN {
    FS = OFS = ","
    numTags = split("aaa,hhh",tags)
}
{
    delete tag2val
    for (i=1; i<=NF; i++) {
        tag = $i
        sub(/=.*/,"",tag)
        tag2val[tag] = $i
    }

    for (i=1; i<=numTags; i++) {
        tag = tags[i]
        printf "%s%s", tag2val[tag], (i<numTags ? OFS : ORS)
    }
}

$ awk -f tst.awk file
aaa=somedata1,hhh=somedata8
aaa=somedata1,hhh=somedata8
aaa=somedata1,hhh=somedata8

Если вы хотите напечатать все возможные поля в каждой строке, то это подход за 2 -прохода, где первый проход просто идентифицирует все возможные поля из каждой строки:

$ cat tst.awk
BEGIN {
    FS = OFS = ","
}
NR==FNR {
    for (i=1; i<=NF; i++) {
        tag = $i
        sub(/=.*/,"",tag)
        if ( !seen[tag]++ ) {
            tags[++numTags] = tag
        }
    }
    next
}
{
    delete tag2val
    for (i=1; i<=NF; i++) {
        tag = $i
        sub(/=.*/,"",tag)
        tag2val[tag] = $i
    }

    for (i=1; i<=numTags; i++) {
        tag = tags[i]
        printf "%s%s", tag2val[tag], (i<numTags ? OFS : ORS)
    }
}

$ awk -f tst.awk file file
aaa=somedata1,bbb=somedata2,ccc=somedata3,eee=somedata5,hhh=somedata8,,,,
aaa=somedata1,,,,hhh=somedata8,ddd=somedata4,fff=somedata6,,
aaa=somedata1,bbb=somedata2,,,hhh=somedata8,,,ggg=somedata9,jjj=somedata11

Если вы просто хотите напечатать поля, которые встречаются во всех строках:

$ cat tst.awk
BEGIN {
    FS = OFS = ","
}
NR==FNR {
    for (i=1; i<=NF; i++) {
        tag = $i
        sub(/=.*/,"",tag)
        cnt[tag]++
    }
    next
}
FNR==1 {
    for (tag in cnt) {
        if ( cnt[tag] == (NR-1) ) {
            tags[++numTags] = tag
        }
    }
}
{
    delete tag2val
    for (i=1; i<=NF; i++) {
        tag = $i
        sub(/=.*/,"",tag)
        tag2val[tag] = $i
    }

    for (i=1; i<=numTags; i++) {
        tag = tags[i]
        printf "%s%s", tag2val[tag], (i<numTags ? OFS : ORS)
    }
}

$ awk -f tst.awk file file
hhh=somedata8,aaa=somedata1
hhh=somedata8,aaa=somedata1
hhh=somedata8,aaa=somedata1

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

$ cat tst.awk
BEGIN {
    FS = OFS = ","
}
NR==FNR {
    for (i=1; i<=NF; i++) {
        tag = $i
        sub(/=.*/,"",tag)
        if ( !cnt[tag]++ ) {
            order[++totTags] = tag
        }
    }
    next
}
FNR==1 {
    for (i=1; i<=totTags; i++) {
        tag = order[i]
        if ( cnt[tag] == (NR-1) ) {
            tags[++numTags] = tag
        }
    }
}
{
    delete tag2val
    for (i=1; i<=NF; i++) {
        tag = $i
        sub(/=.*/,"",tag)
        tag2val[tag] = $i
    }

    for (i=1; i<=numTags; i++) {
        tag = tags[i]
        printf "%s%s", tag2val[tag], (i<numTags ? OFS : ORS)
    }
}

$ awk -f tst.awk file file
aaa=somedata1,hhh=somedata8
aaa=somedata1,hhh=somedata8
aaa=somedata1,hhh=somedata8
2
18.03.2021, 22:28

Если у вас есть возможность использовать Миллер , то ваши данные точно в формате Миллераdkvp(ключ -значение -пара ), и вы можете cutпо имени поля непосредственно:

$ mlr --dkvp cut -f aaa,hhh file.csv
aaa=somedata1,hhh=somedata8
aaa=somedata1,hhh=somedata8
aaa=somedata1,hhh=somedata8

Кроме того, вы можете восстановить отсутствующие поля с помощьюunsparsify:

$ mlr --dkvp unsparsify file.csv
aaa=somedata1,bbb=somedata2,ccc=somedata3,eee=somedata5,hhh=somedata8,ddd=,fff=,ggg=,jjj=
aaa=somedata1,bbb=,ccc=,eee=,hhh=somedata8,ddd=somedata4,fff=somedata6,ggg=,jjj=
aaa=somedata1,bbb=somedata2,ccc=,eee=,hhh=somedata8,ddd=,fff=,ggg=somedata9,jjj=somedata11
1
18.03.2021, 22:28
awk -F "," '{for(i=1;i<=NF;i++){if($i ~ /aaa|hhh/){print $i}}}' filename|sed "N;s/\n/,/g"

выход

aaa=somedata1,hhh=somedata8
aaa=somedata1,hhh=somedata8
aaa=somedata1,hhh=somedata8
0
18.03.2021, 22:28

Теги

Похожие вопросы