Подставлять строки после определенных строк из другого файла - PullRequest
0 голосов
/ 29 апреля 2018

У меня есть три текстовых файла.

Файл 1

300,-4.45479329731605E-08,30.0000000534252
305,-3.24248685321522E-08,30.0000000626148
7505,-6.10348043414643E-08,29.9999998187525
7510,-2.97107304427854E-08,29.9999999033104

Файл 2

305
7510

Когда строки в файле 1 начинаются с чисел, присутствующих в файле 2, я хочу заменить строки в файле 1 следующими строками в файле 3

@1,2.0000,4.0
@2,10.0000,10.0

Желаемый результат:

300,-4.45479329731605E-08,30.0000000534252
@1,2.0000,4.0
7505,-6.10348043414643E-08,29.9999998187525
@2,10.0000,10.0

Редактировать : файлы с окончанием строки Windows.

Ответы [ 3 ]

0 голосов
/ 30 апреля 2018

В awk:

$ awk -F, 'NR==FNR{a[$1];next}$1 in a{getline < "file3"}1' file2 file1
300,-4.45479329731605E-08,30.0000000534252
@1,2.0000,4.0
7505,-6.10348043414643E-08,29.9999998187525
@2,10.0000,10.0

Разъяснения:

$ awk -F, '               # comma delimiter
NR==FNR {                 # process file2
    a[$1]                 # hash to a 
    next                  # process next record in file2
}
$1 in a {                 # process file1. if first field value is in a
    getline < "file3"     # read a record from file3 and *)
}1' file2 file1           # output. mind the file order

*) Если в * 1008 не осталось записей, будет выведена пустая запись.

Редактировать : фиксированный вариант Windows для GNU awk (и mawk, непроверенный в Windows):

$ awk 'BEGIN{FS=",";RS="\r\n"} NR==FNR{a[$1];next}$1 in a{getline < "file3"}1' file2 file1
0 голосов
/ 30 апреля 2018
$ cat tst.awk
BEGIN { FS=OFS="," }
{ sub(/\r$/,"") }
FILENAME == ARGV[1] { idx[FNR] = $1; next }
FILENAME == ARGV[2] { map[idx[FNR]] = $0; next }
$1 in map { $0 = map[$1] }
{ print }

$ awk -f tst.awk file2 file3 file1
300,-4.45479329731605E-08,30.0000000534252
@1,2.0000,4.0
7505,-6.10348043414643E-08,29.9999998187525
@2,10.0000,10.0

Вышеуказанное будет работать в любом awk на любой ОС. Если вы хотите сохранить \r s на выходе, переместите вызов sub() в блок FILENAME==ARGV[1], чтобы он влиял только на file2.

0 голосов
/ 30 апреля 2018

Во-первых. Удобно объединять ваши File 2 и File 3 построчно. Вы можете достичь этого с помощью команды paste:

paste -d"," file2 file3 > file23

Согласно вашему примеру, содержимое файла 2:

305
7510

Содержимое файла3:

@1,2.0000,4.0
@2,10.0000,10.0

Результирующее содержимое файла23:

305,@1,2.0000,4.0
7510,@2,10.0000,10.0

Во-вторых. Затем вы можете использовать простой сценарий AWK, чтобы сделать то, что вам нужно:

awk -v FS="," 'NR==FNR { d[$1]=substr($0,length($1)+2); next } d[$1] { $0=d[$1] } 1' file23 file1

Содержимое файла1:

300,-4.45479329731605E-08,30.0000000534252
305,-3.24248685321522E-08,30.0000000626148
7505,-6.10348043414643E-08,29.9999998187525
7510,-2.97107304427854E-08,29.9999999033104

Выход:

300,-4.45479329731605E-08,30.0000000534252
@1,2.0000,4.0
7505,-6.10348043414643E-08,29.9999998187525
@2,10.0000,10.0

P.S. Обычно такие вопросы, как ваши, рассматриваются не по теме, поскольку вы не пытались решить их самостоятельно. Вы должны включить код в такие вопросы, как этот.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...