Доброго дня учасникам, я тут новенький и если что не так, безжалостно тычте носом куда следует.
Итак, мне нужно написать скрипт, который бы разбирал два файла на строки и, при совпадении второго поля строки первого с третьим полем строки второго файла, он бы записывал то, что в третьем поле первого файла в четвертое поле второго файла. Так как я еще совсем зеленый скриптописатель, углубился в гуглы и наваял вот что#!/usr/local/bin/bash
readfile=file1
writefile=file2
exitfile=exitfile.csv
cat $readfile | while read line;
do
name=`echo $line | awk -F';' '{print $2}' | sed 's/[0-9]//g'`
dlya_vstavki=`echo $line | awk -F';' '{print $3}'`
cat $writefile | while read line1;
do
name1=`echo $line1 | awk -F';' '{print $3}' | sed 's/[0-9]//g'`
if [ "$name" = "$name1" ]
then
cat $writefile | awk -F';' -v code="$dlya_vstavki" '{$4=code; print}' > $exitfile
echo '=== naideno sovpadenie dlya' $name 'i v opisanie dobavleno' $dlya_vstavki '===' >> log
continue
fi
done
doneпроблема в том, что он почему то берет и заполняет четвертое поле каждой строки второго файла третьим полем из первой же строки первого файла, второе поле которого совпадает с третьим полем второго файла.
Может коряво все объяснил, но чую что решение проблемы лежит на поверхности и я как новичек не могу уловить в чем соль.
#!/bin/bashfile1=/tmp/file1
file2=/tmp/file2strnum=1
awk '{ print $2 }' $file1 | while read e2_1
do
e3_2=$(awk '{ if (NR == '$strnum') { print $3 } }' $file2)
if [ "$e2_1" == "$e3_2" ]; then
e3_1=$(awk '{ if (NR == '$strnum') print $3 }' $file1)
awk '{ if (NR == '$strnum') $4="'$e3_1'"; print $0 > "'$file2'" }' $file2
fi
let strnum=$strnum+1
doneЗамены произведутся в $file2 иначе (если надо другой output.file) исправьте строку
с awk '{ if (NR == '$strnum') $4="'$e3_1'"; print $0 > "'$file2'" }' $file2
на awk '{ if (NR == '$strnum') $4="'$e3_1'"; print $0 > /tmp/out }' $file2
>[оверквотинг удален]
> awk '{ if (NR == '$strnum')
> $4="'$e3_1'"; print $0 > "'$file2'" }' $file2
> fi
> let strnum=$strnum+1
> done
> Замены произведутся в $file2 иначе (если надо другой output.file) исправьте строку
> с awk '{ if (NR == '$strnum') $4="'$e3_1'"; print $0 > "'$file2'"
> }' $file2
> на awk '{ if (NR == '$strnum') $4="'$e3_1'"; print $0 > /tmp/out
> }' $file2скрипт хороший, но даже не запуская я вижу одну проблему, заключается она в том, что в file2 есть произвольное количество совпадений каждого второго поля file1, эти совпадения стоят подряд, но сколько их по количеству нельзя сказать наверняка. их может быть 2 3 5 или N. и получается? что переменная strnum сбивает весь скрипт, привязывая каждую итерацию к каждой строке. В итоге опять таки, совпал всего один варант как положено, видимо чисто случайно и везде 4 поле выходного файла заполнилось одним и тем же значением.
Исходные файлы:
file1
==========
fs fsd fdd fs123
fs 333 6fdd fs123
fs 2fsd 7fdd fs123
fs 333 8fdd fs123
fs 333 9fdd fs123file2
==========
fs fsd 00fdd 444
fs ggg 333 444 fs123
fs ggg 333 444 fs123
fs ggg ==3fsd 444 fs123
fs ggg 333 444 fs123
fs ggg ==4fsd 444 fs123
fs hhh4fsd= ==009fdd 444
fs hhh 4fsd 444 fs123
fs hhh 333 444 fs123Как видно, замены должны быть произведены во 2, 5 строках, что и произошло.
Результат выполнения скрипта
============================
cat -n /tmp/file2
1 fs fsd 00fdd 444
2 fs ggg 333 6fdd fs123
3 fs ggg 333 444 fs123
4 fs ggg ==3fsd 444 fs123
5 fs ggg 333 9fdd fs123
6 fs ggg ==4fsd 444 fs123
7 fs hhh4fsd= ==009fdd 444
8 fs hhh 4fsd 444 fs123
9 fs hhh 333 444 fs123Или я не вижу своей ошибки/не понял Вашей трактовки. Или Вы ошибаетесь.
Суть скрипта: перебираю второй элемент файла $file1 построчно. Для каждой строки получаю 3 элемент $file2 в строке с тем же номером. В случае, если они равны, нахожу 3 элемент в первом файле и заменяю 4ый awk { $4 } во втором.
К недостаткам способа можно отнести, что $file2 каждый раз перезаписывается целиком. Как сказано ниже, ничего не мешает считать его в $var, по окончании правки которого, слить в файл.
> cat $writefile | awk -F';' -v code="$dlya_vstavki" '{$4=code; print}' > $exitfileна самом деле, на сколько я понял, играясь с отладкой моего опуса, вся проблема только в этой строке. здесь же скрипт берет весь файл и заменяет во всем четвертое поле тем значением переменной $dlya_vstavki которое является актуальным для данной итерации.
у меня в голове никак не может родиться алгоритм, по которому бы скрипт держал в уме номер строки вложенного цикла и менял 4ое поле при соблюдении условия только в этой строке, а не во всем файле. Сейчас кручу варианты по использованию скрипта erra22, но пока никак не выходит.
>> cat $writefile | awk -F';' -v code="$dlya_vstavki" '{$4=code; print}' > $exitfile
> на самом деле, на сколько я понял, играясь с отладкой моего опуса,
> вся проблема только в этой строке. здесь же скрипт берет весь
> файл и заменяет во всем четвертое поле тем значением переменной $dlya_vstavki
> которое является актуальным для данной итерации.
> у меня в голове никак не может родиться алгоритм, по которому бы
> скрипт держал в уме номер строки вложенного цикла и менял 4ое
> поле при соблюдении условия только в этой строке, а не во
> всем файле. Сейчас кручу варианты по использованию скрипта erra22, но пока
> никак не выходит.Ничего не мешает писать в переменную результат "моего" awk, несколько раз модифицировать и лишь в итоге дампить его в файл.
> Или я не вижу своей ошибки/не понял Вашей трактовки. Или Вы ошибаетесь.
> Суть скрипта: перебираю второй элемент файла $file1 построчно. Для каждой строки получаю
> 3 элемент $file2 в строке с тем же номером. В случае,
> если они равны, нахожу 3 элемент в первом файле и заменяю
> 4ый awk { $4 } во втором.
> К недостаткам способа можно отнести, что $file2 каждый раз перезаписывается целиком. Как
> сказано ниже, ничего не мешает считать его в $var, по окончании
> правки которого, слить в файл.Так я и говорю, что количество строк первого файла не совпадает с количеством строк второго файла. Во втором строк с совпадением может быть произвольное количество до 10, единственное что постоянно, что повторяющиеся строки стоят подряд. Потому строка с номером N в пером файле и совпала всего единожды, по всей видимости совершенно случайно.
>Ничего не мешает писать в переменную результат "моего" awk, несколько раз модифицировать и лишь в итоге дампить его в файл.
А можно тут поподробней? Мне самое интересное как из переменной записать в файл заменив поле\всю строку, с полным сохранением синтаксиса исходного файла. А не заменять поле всех строк файла.
>[оверквотинг удален]
>> правки которого, слить в файл.
> Так я и говорю, что количество строк первого файла не совпадает с
> количеством строк второго файла. Во втором строк с совпадением может быть
> произвольное количество до 10, единственное что постоянно, что повторяющиеся строки стоят
> подряд. Потому строка с номером N в пером файле и
> совпала всего единожды, по всей видимости совершенно случайно.
>>Ничего не мешает писать в переменную результат "моего" awk, несколько раз модифицировать и лишь в итоге дампить его в файл.
> А можно тут поподробней? Мне самое интересное как из переменной записать в
> файл заменив поле\всю строку, с полным сохранением синтаксиса исходного файла. А
> не заменять поле всех строк файла.Млин, у Вас было сказано "нужно написать скрипт, который бы разбирал два файла на строки", потому скрипт и смотрел строку N в файле 1 и строку с тем же номером в файле 2, после чего, при выполнении условия, модифицировал файл 2. Никакого рандома и "случайностей". Проверяйте и не несите бред.
Если в файле 1 надо для каждого столбца каждой строки в файле 2 найти все совпадения, это надо было указать в задаче явно, а не кривотолками "...я и говорю...".Чтобы пилить переменную:
1) читаем файл 2 в нее: var=$(cat 2)
2) пример замены: echo "$var" | awk ...
3) дампим echo "$var" > dump
>[оверквотинг удален]
> 1 и строку с тем же номером в файле 2, после
> чего, при выполнении условия, модифицировал файл 2. Никакого рандома и "случайностей".
> Проверяйте и не несите бред.
> Если в файле 1 надо для каждого столбца каждой строки в файле
> 2 найти все совпадения, это надо было указать в задаче явно,
> а не кривотолками "...я и говорю...".
> Чтобы пилить переменную:
> 1) читаем файл 2 в нее: var=$(cat 2)
> 2) пример замены: echo "$var" | awk ...
> 3) дампим echo "$var" > dumpооо, вот теперь я тебя понял, долго вникал, много раз перечитал, но заставил мозг работать, теперь все работает, спасибо!