나는 4개를 갖고 있다데이터 세트파일, 네 번째 파일의 값을 기반으로 세 개의 파일 집합을 업데이트하고 싶습니다.
- 파일 1이름이 포함되어 있습니다.
- 파일_2디지털 ID.
- 파일_3다음의 ID를 포함합니다.파일 1그리고파일_2, 각 ID 조합 쌍에 해당하는 값입니다.
- 파일_4새로운 이름의 조합을 포함하는 값입니다.
내가해야 할 일은 추가하는 것입니다파일_4새 이름은파일 1그리고파일_2, 점진적으로 자동으로 ID를 생성합니다. 그런 다음 값을파일_3새로운 ID 조합을 기반으로 합니다. 문제는 간단합니다. 아래 예에서 설명하는 것처럼 문제를 조금 복잡하게 만드는 것은 쉼표로 구분된 하위 필드가 있다는 것입니다."1,2,3"일부에서는데이터 세트에스.
이를 달성하려면 스크립트를 사용해야 하지만 사용하기가 더 쉬울 수도 있습니다.SQL.
파일 1
nid,vname
1,name1
2,name2
3,name3
파일_2
did,dname
1,"s1,s2,s3"
2,s4
3,"s5,s6"
파일_3
nid,did,value
1,1,aa
1,2,gg
1,3,tt
2,1,aa
2,2,ag
2,3,at
3,1,aa
3,2,tt
파일_4
new_name,new_dataset,value
name1,"s7,s8",aa
name2,"s9,s10",gg
name8,"s1,s2,s3",aa
따라서 업데이트된 세 개의 파일은 다음과 같아야 합니다.
File_1_업데이트
nid,vname
1,name1
2,name2
3,name3
4,name8
File_2_업데이트
did,dname
1,"s1,s2,s3"
2,s4
3,"s5,s6"
4,"s7,s8"
5,"s9,s10"
File_3_업데이트
nid,did,value
1,1,aa
1,2,gg
1,3,tt
1,4,aa
2,1,aa
2,2,ag
2,3,at
2,5,gg
3,1,aa
3,2,tt
4,1,aa
답변1
데이터가 게시한 것과 정확히 같다고 가정하면 일반 bash에서 다음을 수행할 수 있습니다. (경고하다: 파일을 제자리에서 수정합니다. 테스트 전 백업을 꼭 해주시기 바랍니다. )
처음 두 파일을 관리하는 여러 기능:
next_id() {
file="$1"
# assumes file is sorted by id
echo $(( $(tail -n 1 $file|cut -d, -f1) + 1 ))
}
가설파일 1그리고파일 2id 열을 기준으로 정렬하면 마지막 행의 첫 번째 부분을 가져와서 1씩 증가시켜 다음 ID를 생성합니다.
find_or_create_id() {
file="$1"
item="$2"
# check if we already have that item
id=$(grep -m 1 ",$item$" "$file" 2> /dev/null)
if [[ $? -ne 0 ]] ; then
# generate the next id, append
id=$(next_id "$file")
echo "$id,$item" >> "$file"
else
# got it already
id=${id/,*}
fi
echo "$id"
}
처음 두 파일 중 하나에서 항목(vname 또는 dname)을 찾습니다. 발견되면 기존 ID가 반환됩니다. 그렇지 않은 경우 다음 ID를 생성하여 파일에 다시 저장하십시오.
올바른 하위 문자열이 있으면 주요 부분은 매우 간단합니다.
while read line ; do
col1=${line/,*} # everything up to first ,
col3=${line//*,} # everything after last ,
col2=${line%,*} # everything after first ,
col2=${col2#*,} # everything before last ,
id1=$(find_or_create_id file1 "$col1")
id2=$(find_or_create_id file2 "$col2")
# don't insert duplicates
if ! grep -m 1 -q "^$id1,$id2," file3 ; then
echo "$id1,$id2,$col3" >> file3
fi
done < <(tail -n +2 file4)
이것은 것이다아니요마지막 파일을 순서대로 삽입하면 끝에 새 줄이 추가됩니다.
즉, 이러한 파일 중 크기가 큰 경우 데이터베이스가 적합할 것입니다. 데이터베이스 서버가 필요하지 않다면 SQLite를 고려해보세요.
순차 ID에 신경 쓰지 않고(단순히 다르다는 점만) integer primary key autoincrement
테이블 1과 테이블 2에 ID(vname 및 dname의 고유 키 포함)를 추가했다고 가정하면 업데이트는 다음과 같습니다(아마도 이 방법보다 더 나을 것입니다). 좀 더 미묘한 접근 방식 insert or ignore
):
insert or ignore into tab1(vname) select distinct vname from tab4;
insert or ignore into tab2(dname) select distinct dname from tab4;
insert or ignore into tab3(id1,id2,value)
select tab1.id, tab2.id, tab4.value
from tab4
left join tab1 on tab1.vname = tab4.vname
left join tab2 on tab2.dname = tab4.dname;
SQLite "
는 .
.separator ,
.import fileX tabX
적어도 현재 가지고 있는 샘플에 대해서는 Right Thing™을 수행하십시오.
간단한 아키텍처:
create table tab1 (id integer primary key autoincrement, vname text);
create unique index tab1_vname on tab1(vname);
create table tab2 (id integer primary key autoincrement, dname text);
create unique index tab2_dname on tab2(dname);
create table tab3 (id1 int, id2 int, value text,
constraint tab3_pk primary key(id1, id2));
create table tab4 (vname text, dname text, value text);
답변2
이것은2/3답, 활용*닉스소프트웨어 도구. File_1_업데이트:
head -n 1 file_1 ; \
{ tail -n +2 file_1 | cut -d ',' -f 2 ; \
tail -n +2 file_4 | cut -d ',' -f 1 ; } | \
sort -n | uniq | nl -s ',' | tr -d ' '
산출:
nid,vname
1,name1
2,name2
3,name3
4,name8
File_2_업데이트:
head -n 1 file_2 ; \
{ tail -n +2 file_2 | cut -d ',' -f 2- ; \
tail -n +2 file_4 | cut -d ',' -f 2- | \
rev | cut -d ',' -f 2- | rev ; } | \
sort -n | uniq | nl -s ',' | tr -d ' '
산출:
did,dname
1,"s1,s2,s3"
2,s4
3,"s5,s6"
4,"s7,s8"
5,"s9,s10"