Разделение файлов CSV на основе части столбца

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

sed 's#/[^/]*\.design$##' final.txt

Чтобы выполнить редактирование места -, используйте sed -iс приведенным выше выражением (существуют небольшие вариации того, как работает флаг -i, но это будет работать, например, с GNU sed).

Регулярное выражение /[^/]*\.design$соответствует /, за которым следует любое количество символов, отличных от -/, и литеральная строка .designв конце строки.

1
03.01.2021, 19:51
3 ответа

Как насчет:

awk -F', ' '
  { date = substr($2,1,10) }
  !(date in outfile) { outfile[date] = "file_" (++numout) ".csv" }
  { print > outfile[date] }
' file.csv

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

  { print >> outfile[date]; close(outfile[date]) }
4
18.03.2021, 22:38

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

<infile sort -t, -k2 \
|awk -F, '{
     substr($2,1,10)!=prev && nxt++;
     print >>("file_"nxt".csv"); close("file_"nxt".csv");
     prev=substr($2,1,10);
}'
0
18.03.2021, 22:38
$ cat tst.sh
#!/usr/bin/env bash

awk -F'[ -]' -v OFS='\t' '{print $2$3, NR, $0}' "${@:--}" |
sort -k1,1n -k2,2n |
cut -f3- |
awk -F'[ -]' '
    { curr = $2$3 }
    curr != prev {
        close(out)
        out = "file_" (++cnt) ".csv"
        prev = curr
    }
    { print > out }
'

./tst.sh file

$ head file_*
==> file_1.csv <==
id1, 2017-04-28T19:59:00, 80
id2, 2017-04-28T03:14:35, e4
id5, 2017-04-28T00:31:54, 65
id7, 2017-04-28T21:04:30, 7f

==> file_2.csv <==
id0, 2020-12-12T07:18:26, 7f
id3, 2020-12-12T23:45:09, ff
id4, 2020-12-12T09:12:34, a1
id6, 2020-12-12T20:13:47, 45

Описанное выше будет надежно, эффективно и переносимо работать с любым POSIX awk, sort и cut и сохранит порядок ввода в выходных файлах.

Вот как первые 3 шага переупорядочивают содержимое входного файла:

$ cat file
id0, 2020-12-12T07:18:26, 7f
id1, 2017-04-28T19:59:00, 80
id2, 2017-04-28T03:14:35, e4
id3, 2020-12-12T23:45:09, ff
id4, 2020-12-12T09:12:34, a1
id5, 2017-04-28T00:31:54, 65
id6, 2020-12-12T20:13:47, 45
id7, 2017-04-28T21:04:30, 7f

чтобы к моменту запуска окончательного awk-скрипта в нем были строки, упорядоченные по году+месяцу от $2, и сохранялся порядок ввода для всех строк с одинаковой датой+временем:

$ awk -F'[ -]' -v OFS='\t' '{print $2$3, NR, $0}' file
202012  1       id0, 2020-12-12T07:18:26, 7f
201704  2       id1, 2017-04-28T19:59:00, 80
201704  3       id2, 2017-04-28T03:14:35, e4
202012  4       id3, 2020-12-12T23:45:09, ff
202012  5       id4, 2020-12-12T09:12:34, a1
201704  6       id5, 2017-04-28T00:31:54, 65
202012  7       id6, 2020-12-12T20:13:47, 45
201704  8       id7, 2017-04-28T21:04:30, 7f

$ awk -F'[ -]' -v OFS='\t' '{print $2$3, NR, $0}' file | sort -k1,1n -k2,2n
201704  2       id1, 2017-04-28T19:59:00, 80
201704  3       id2, 2017-04-28T03:14:35, e4
201704  6       id5, 2017-04-28T00:31:54, 65
201704  8       id7, 2017-04-28T21:04:30, 7f
202012  1       id0, 2020-12-12T07:18:26, 7f
202012  4       id3, 2020-12-12T23:45:09, ff
202012  5       id4, 2020-12-12T09:12:34, a1
202012  7       id6, 2020-12-12T20:13:47, 45

$ awk -F'[ -]' -v OFS='\t' '{print $2$3, NR, $0}' file | sort -k1,1n -k2,2n | cut -f3-
id1, 2017-04-28T19:59:00, 80
id2, 2017-04-28T03:14:35, e4
id5, 2017-04-28T00:31:54, 65
id7, 2017-04-28T21:04:30, 7f
id0, 2020-12-12T07:18:26, 7f
id3, 2020-12-12T23:45:09, ff
id4, 2020-12-12T09:12:34, a1
id6, 2020-12-12T20:13:47, 45
1
18.03.2021, 22:38

Теги

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