Как разделить большой файл на маленькие файлы и файлы с именами по столбцам

#bash #shell #awk

#bash #оболочка #awk

Вопрос:

это мой csv-ввод, record.csv

 AAAAA_01|2020-12-28
BBBBB_01|2021-05-24
CCCCC_01|2021-05-17
DDDDD_01|2021-05-19
EEEEE_01|2021-05-20
FFFFF_01|2021-05-30
GGGGG_01|2021-05-25
HHHHH_01|2020-12-23
 

надеюсь, я смогу разделить csv на текстовый формат ниже и назвать его именем столбца 1 (только первые 5 символов)

AAAAA.txt

 Name: AAAAA
Date: 2020-12-28
 

BBBBB.txt

 Name: BBBBB
Date: 2021-05-24
 

Я попробовал приведенный ниже сценарий, имя файла экспортировалось как xaa, xab……
но я понятия не имею, как переименовать его в желаемое имя…

 cat record.csv | awk 'BEGIN{FS="|";OFS="|"
}{ 
print "Name: "substr($1,1,5)
print "Date:" $2

}'| split -l 12
 

Спасибо!


 awk -F'|' '                                    
 f=substr($1,1,5)".txt"                                    
{
print "Name: "substr($1,1,5) >f
print "Date: "$2 >f
print "Remarks" >f
close(f)  
}
' record.csv
 

Ответ №1:

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

 awk -F'|' '{name=substr($1,1,5); print "Name: "name ORS "Date:" $2 > name".txt"}' abcde.txt
 

например

 $ ls
 abcde.txt

$ cat abcde.txt
 AAAAA_01|2020-12-28
 BBBBB_01|2021-05-24
 CCCCC_01|2021-05-17
 DDDDD_01|2021-05-19
 EEEEE_01|2021-05-20
 FFFFF_01|2021-05-30
 GGGGG_01|2021-05-25
 HHHHH_01|2020-12-23

$ awk -F'|' '{name=substr($1,1,5); print "Name: "name ORS "Date:" $2 > name".txt"}' 
 abcde.txt

$ ls
 AAAAA.txt  abcde.txt  BBBBB.txt  CCCCC.txt  DDDDD.txt  
 EEEEE.txt  FFFFF.txt  GGGGG.txt  HHHHH.txt

$ cat AAAAA.txt
 Name: AAAAA
 Date:2020-12-28
$ cat BBBBB.txt
 Name: BBBBB
 Date:2021-05-24
 

Комментарии:

1. Большое спасибо! Поскольку в будущем может быть добавлено больше строк, могу ли я узнать, как разделить на несколько строк после «печати»? лайки, 1-я строка: «Имя:» имя, 2-я строка: «Дата:» $ 2, 3-я строка: «Примечания:»

2. сославшись на оба ответа, я добавил свое решение внизу, будут ли какие-нибудь более умные способы для будущего редактирования? в будущем может быть добавлено гораздо больше строк

Ответ №2:

Пример ввода:

 $ cat record.csv
AAAAA_01|2020-12-28
BBBBB_01|2021-05-24
CCCCC_01|2021-05-17
DDDDD_01|2021-05-19
EEEEE_01|2021-05-20
FFFFF_01|2021-05-30
GGGGG_01|2021-05-25
HHHHH_01|2020-12-23
 

Одно awk решение:

 $ awk -F'[_|]' '                                    # define underscore (_) and pipe (|) as input delimiters
{ f=$1".txt"                                        # define output file name (f) as $1.txt
  printf "Name: %snDate: %sn", $1, $3 > f         # format data as desired and write to output file (f)
  close(f)                                          # close the output file (some versions of awk will crash if too many file descriptors are kept open at the same time)
}
' record.csv
 

Или как однострочный:

 $ awk -F'[_|]' '{ f=$1".txt" ; printf "Name: %snDate: %sn", $1, $3 > f; close(f)}' record.csv
 

Вышесказанное генерирует следующее:

 $ ls -1 [A-Z]????.txt
AAAAA.txt
BBBBB.txt
CCCCC.txt
DDDDD.txt
EEEEE.txt
FFFFF.txt
GGGGG.txt
HHHHH.txt

$ for fname in [A-Z]????.txt
do
    echo "             ${fname}"
    cat "${fname}"
done
             AAAAA.txt
Name: AAAAA
Date: 2020-12-28
             BBBBB.txt
Name: BBBBB
Date: 2021-05-24
             CCCCC.txt
Name: CCCCC
Date: 2021-05-17
             DDDDD.txt
Name: DDDDD
Date: 2021-05-19
             EEEEE.txt
Name: EEEEE
Date: 2021-05-20
             FFFFF.txt
Name: FFFFF
Date: 2021-05-30
             GGGGG.txt
Name: GGGGG
Date: 2021-05-25
             HHHHH.txt
Name: HHHHH
Date: 2020-12-23