Bash 스크립트에서 $REPLY의 문자열 토큰화

Bash 스크립트에서 $REPLY의 문자열 토큰화

이것은 내 첫 번째 게시물입니다. StackExchage, Google, Wiki, GNU, 인터넷 이전에는 어떻게 관리했는지 모르겠습니다 :)

현재 다음과 같은 SQL 데이터베이스 생성기 bash 스크립트를 작성하는 방법을 찾으려고 노력 중입니다.

renice -n 19 $$;

idx=32768;
dbt='Radix_en';

cat Domains_en.txt;
cat Tables_en.txt;

while read; 
do
checks="$(echo -n $REPLY | md5sum)";
checks=${checks%"  -"};

echo "insert into $dbt values ($idx,'$(uuidgen)','${checks}',$REPLY);";
idx=$((idx+1));

done < Data.txt;
echo "commit;";

데이터는 Data.txt에서 제공되며 현재 형식은 다음과 같습니다.

'NUMBER','US_EN','LATIN','GREEK','GERMAN'
0,'zero','nulla','μηδέν','Null'
1,'one','Unum','ένα','ein'

출력은 유효한 SQL입니다(Firebird용).

create domain ...;
create domain ...;
commit;

create table ( ... );
create table ( ... );
commit;

insert into Radix_en values (32768,'dff0207a-591f-4435-9f8b-7b9b3e6ba2c1','d1f77359b3f7236806489ba3108c771f','NUMBER','US_EN','LATIN','GREEK','GERMAN');
insert into Radix_en values (32769,'5ef0e634-5c96-4ae4-92a8-0d68c02ffeb6','4e3f710600230cf0520bf32269511062',0,'zero','nulla','μηδέν','Null');
insert into Radix_en values (32770,'eae9cacc-3ee3-4471-afad-e5af201da435','9ab2f782988416431238ec63277b11df',1,'one','Unum','ένα','ein');
commit;

구분 기호를 포함한 전체 텍스트 줄을 생성하는 대신 각 필드에 대해 MD5 체크섬을 생성하는 방법을 찾고 싶습니다.

Data.txt 형식은 아직 확정되지 않았으므로 이를 가능하게 하거나 더 쉽게 만들 수 있는 형식으로 변경할 수 있습니다.

또한, 여러 개의 개별 단계가 있어야 하는 경우에도 괜찮습니다. 전체 프로세스가 스크립트로 작성되고 자동화되어야 하기 때문입니다. Data.txt를 먼저 처리한 다음 이 스크립트를 통해 실행할 생각인데 프로세스를 최대한 간단하게 만들고 싶습니다. 다양한 Data.txt 파일의 수가 상당히 많을 수 있으며 포함해야 할 다른 프로세서도 많이 있습니다.

사실 저는 bash 스크립팅에 대해서도 더 많이 배우려고 노력하고 있으며, 구체적인 해결책보다는 이 문제에 대한 전문가의 접근 방식과 조언을 찾고 싶습니다.

내 게시물의 제목이 나에게 필요한 솔루션인지 확실하지 않으므로 내 문제와 관련이 있습니다. 이 글을 제가 정기적으로 방문하는 슈퍼유저에 게시해야 할지, 아니면 여기에 게시해야 할지 잘 모르겠습니다. 그래서 여기에 먼저 글을 올릴게요, 조금 부족했다면 죄송합니다.

감사해요!

샌들

... 2014년 8월 23일 오전 3시에 더 많은 콘텐츠를 추가하도록 편집되었습니다.

IFS를 사용하는 mikeserv 덕분에 작동하므로 내 스크립트는 이제 다음과 같습니다.

renice -n 19 $$ > /dev/null; #for now

idx=32768;
dbt='Radix_en';

cat Domains_en.txt;
cat Tables_en.txt;

while read; 
do

gid="$idx,'$(uuidgen)'";

IFS=,; set -f # no gobbling!
echo "insert into $dbt values ($gid";
    for field in $REPLY
    do  
    printf '%s' ",$field,'";
    printf '%s' "$field" | md5sum;
    done | cut -d\  -f1;


echo "$var);";

idx=$((idx+1));

done < Data.txt;

출력은 훌륭하고 줄 바꿈을 사용하면 텍스트 편집/검색이 훨씬 쉬워지며 Firebird는 한 가지를 제외하고는 여전히 만족합니다.

출력은 다음과 같습니다.

create domain ...;
create domain ...;
commit;

create table ( ... );
create table ( ... );
commit;

insert into Radix_en values (32768,'303f8957-57cf-4485-ace4-d21c7cf144e6'
,'NUMBER','722d79c16b51fe86610972b8d950038c
,'US_EN','b63fb39e32b062c76694bec58c4f8c67
,'LATIN','fd6f27a3c59111fc2a0b5e452595ef3d
,'GREEK','c081310697bb6b7d7bed5034824e2530
,'GERMAN','15db1d0e1b0861d8ac1f391db801493a
);
insert into Radix_en values (32769,'e7fdf095-d31c-4c59-a23b-7ea67db7aefb'
,0,'cfcd208495d565ef66e7dff9f98764da
,'zero','01b40535afbfd9611e910f58f4ab5146
,'nulla','584edd0b6638798dee53e2c23e84e2d1
,'μηδέν','cd3ed2f1039ed8668b4d48e742bd2e5b
,'Null','e0a93a9e6b0eb1688837d8bab9b4badb
);
insert into Radix_en values (32770,'a21916b5-2a05-4656-ad4e-c8cfee1abfcc'
,1,'c4ca4238a0b923820dcc509a6f75849b
,'one','7e31533231a12e4a560a18ac8cd02112
,'Unum','05d92bcbffbf59b375f25945e9af2dd0
,'ένα','826f5e2d5ba7ace48f4d6fe3c5e2925f
,'ein','dcc09a2cb665ca332d1689cb11aff592
);
commit;

md5 해시 끝에 구분 기호가 누락되어 있으며 파이프와 출력을 협상하는 방법을 모르겠습니다. 내가 여기서 이해하지 못하는 것은 무엇입니까?

이 특별한 경우 데이터 필드는 프로그래밍 가능 IC에 대한 코드를 보유하므로 구분 기호 사이의 체크섬에 추가 문자가 허용되지 않거나 지금까지 그렇게 보입니다. 다시 말하지만, 코드는 ASCII 형식이고 구분 기호는 ASCII의 일부가 아니므로 안전합니다. Firebird는 ASCII가 아닌 콘텐츠도 거부합니다.

IFS가 방금 보여준 몇 가지 새로운 문제(예, Windows의 파일 경로)로 이미 어려움을 겪고 있으므로 이 스크립트를 완료하는 방법을 친절하게 알려주실 수 있다면 좋겠습니다. 나는 이 스크립트가 일반 ASCII에서 어떻게 작동하는지 살펴보고 더 많은 질문이 포함된 또 다른 게시물을 작성하고 싶습니다.

도움을 주셔서 다시 한번 감사드립니다!

샌들

...2014년 8월 30일 오후 7시 최종 버전으로 수정됨

cut을 sed로 바꾸는 것이 작동하는 것 같습니다. Firebird 필드 입력은 여전히 ​​세미콜론(')을 이스케이프하고 또 다른 동일한 세미콜론을 추가해야 하며, 데이터 파일의 현재 쉼표 IFS 구분 기호는 여전히 비ASCII 구분 기호로 대체되어야 합니다. 스크립트는 여전히 재귀 파일 목록이 아닌 단일 파일 입력입니다. echo는 아마도 printf로 대체되어야 할 것입니다.

Shebang이 없는 최종 스크립트는 다음과 같습니다.

renice -n 19 $$ >> Radix_en_log.txt;

idx=32768; dbt='Radix_en';
cat Domains_en.txt; cat Tables_en.txt;

while read;     do
gid="$idx,'$(uuidgen)'";

IFS=,; set -f;
echo "insert into $dbt values ($gid";
    for field in $REPLY
    do  
        printf '%s' ",$field,'"; printf '%s' "$field" | md5sum;
    done | sed "s/[ ][ ][-]/\'/g"; printf '%s\n' ");";
    idx=$((idx+1));
        done < Data.txt;
echo "commit;";

출력은 다음과 같습니다.

create domain ...;
create domain ...;
commit;

create table ( ... );
create table ( ... );
commit;

insert into Radix_en values (32768,'2f675b86-b2b4-4e52-b000-e6a8cf0f3dca'
,'NUMBER','722d79c16b51fe86610972b8d950038c'
,'US_EN','b63fb39e32b062c76694bec58c4f8c67'
,'LATIN','fd6f27a3c59111fc2a0b5e452595ef3d'
,'GREEK','c081310697bb6b7d7bed5034824e2530'
,'GERMAN','15db1d0e1b0861d8ac1f391db801493a'
);
insert into Radix_en values (32769,'e2afcd65-9a1b-49e3-baf1-74b0619a4776'
,0,'cfcd208495d565ef66e7dff9f98764da'
,'zero','01b40535afbfd9611e910f58f4ab5146'
,'nulla','584edd0b6638798dee53e2c23e84e2d1'
,'μηδέν','cd3ed2f1039ed8668b4d48e742bd2e5b'
,'Null','e0a93a9e6b0eb1688837d8bab9b4badb'
);
insert into Radix_en values (32770,'f51b72eb-d64f-4e9e-ab49-8954df9505cd'
,1,'c4ca4238a0b923820dcc509a6f75849b'
,'one','7e31533231a12e4a560a18ac8cd02112'
,'Unum','05d92bcbffbf59b375f25945e9af2dd0'
,'ένα','826f5e2d5ba7ace48f4d6fe3c5e2925f'
,'ein','dcc09a2cb665ca332d1689cb11aff592'
);
commit;

감사해요!

샌들

답변1

쉘에는 내장된 가변 확장 필드 구분자가 있습니다. 따라서 문자열이 있고 구분 기호가 고정되어 있으면 다음을 수행할 수 있습니다.

var=32768,'dff0207a-591f-4435-9f8b-7b9b3e6ba2c1','d1f77359b3f7236806489ba3108c771f','NUMBER','US_EN','LATIN','GREEK','GERMAN'
(   IFS=,; set -f
    for field in $var
    do  printf '\n%s\n\t' "$field - md5:" >&2
        printf %s "$field" |
        md5sum
    done |
    cut -d\  -f1
)

32768 - md5:
        f43764367fa4b73ba947fae71b0223a4

dff0207a-591f-4435-9f8b-7b9b3e6ba2c1 - md5:
        0983e6c45209f390461c1b1df9320674

d1f77359b3f7236806489ba3108c771f - md5:
        07d82ab57ba81f991ab996bd7c5a0441

NUMBER - md5:
        34f55eca38e0605a84f169ff61a2a396

US_EN - md5:
        c9d3e580b7b102e864d9aea8703486ab

LATIN - md5:
        0e869135050d24ea6e7a30fc6edbac6c

GREEK - md5:
        d4cacc28e56302bcec9d7af4bba8c9a7

GERMAN - md5:
        ed73cca110623766d7a2457331a4f373

이것은 나처럼 개행으로 구분된 md5 목록을 제공할 것입니다.

IFS=,변수 유형 쉘 확장이 수행될 때 쉘이 이를 ,대신 문자로 분할해야 함을 지정하는 데 사용됩니다 <space><newline><tab>. 이것이 기본값입니다. set -f쉘이 인용되지 않은 확장에서 파일 glob을 발견하면 확장되지 않아야 함을 지정하는 데 사용됩니다. 따라서 echo *현재 디렉토리의 내용에 관계없이 glob만 인쇄됩니다.*

$var쉘의 각 쉼표 printf "$field" | md5sum로 구분된 필드에 대해 필드당 한 번, 구분 기호 문자열 없이 질문의 의미를 이해합니다. 마지막으로 각 출력 라인이 수신되면 끝에 있는 몇 개의 공백의 합을 잘라냅니다 cut. -대부분의 출력은 실제로 볼 수만 stderr있습니다 .cutmd5sums

관련 정보