NF 및 for 루프를 사용하여 스크립트를 최적화하는 방법

NF 및 for 루프를 사용하여 스크립트를 최적화하는 방법

여러 개의 파일이 있는데 각각 열 수가 다릅니다. 데이터베이스에 삽입하기 위해 변환하고 싶습니다.

예를 들어 파일 test01은 다음과 같습니다.

0001    000000000000001 john smith  45  500
0002    000000000000002 peter jackson   20  80
0003    000000000000002 robert brown    35  100
0004    000000000000007 sarah white 40  300

내가 원하는 출력은 다음과 같습니다.

('0001','000000000000001','john smith','45','500'),
('0002','000000000000002','peter jackson','20','80'),
('0003','000000000000002','robert brown','35','100'),
('0004','000000000000007','sarah white','40','300');

이를 달성하기 위해 다음 스크립트를 사용합니다.

cat test01 |awk -F'\t' '{print "('\''"$1"'\'','\''"$2"'\'','\''"$3"'\'','\''"$4"'\'','\''"$5"'\''),"}' |sed '$ s/.$/;/' 

잘 작동합니다. 문제는 열 수가 다른 다른 파일을 찾을 때 발생하므로 스크립트를 수동으로 수정해야 합니다.

AWK의 변수 NF를 사용하여 열 수를 얻을 수 있다는 것을 알고 있지만 스크립트에서 이 변수를 for 루프와 어떻게 결합합니까?

내가 시도할 때

cat test01 | awk '{for (i = 1; i <= NF; i++){print $i"'\'','\''"}}'

나는 다음과 같은 결과를 얻습니다.

0001','
000000000000001','
john','
smith','
45','
500','
0002','
000000000000002','
peter','
jackson','
20','
80','
0003','
000000000000002','
robert','
brown','
35','
100','
0004','
000000000000007','
sarah','
white','
40','
300','

답변1

입력 파일이 탭으로 구분된 경우 다음을 시도해 볼 수 있습니다.

awk -F"\t" -v q="'" -v OFS="','" '$1=$1 {print "(" q $0 q ");"}' filename

또는 인쇄 기능에 따옴표를 삽입하세요.

awk -F"\t" -v OFS="','" '$1=$1 {print "(" "\x27" $0 "\x27" ");"}' filename

답변2

GNU 사용 sed:

$ sed -e "s/^/('/" -e "s/\t/','/g" -e "s/$/'),/" -e '$s/.$/;/' file
('0001','000000000000001','john smith','45','500'),
('0002','000000000000002','peter jackson','20','80'),
('0003','000000000000002','robert brown','35','100'),
('0004','000000000000007','sarah white','40','300');

스크립트 sed는 네 부분으로 나뉩니다.

  1. s/^/('/줄의 시작 부분을 ('.
  2. s/\t/','/g탭을 으로 교체하세요 ','. GNU가 필요한 부분입니다 sed. 다른 sed구현의 경우 대신 리터럴 탭 문자를 삽입하세요 \t.
  3. s/$/'),/줄의 끝 부분을 로 바꿉니다 '),.
  4. $s/.$/;/마지막 줄의 끝 부분에 있는 쉼표를 (만) 로 바꿉니다 ;.

답변3

초기 스크립트에서 원하는 것과 동일한 동작을 달성하려면 awk의 "printf" 메소드를 사용할 수 있습니다. "print"로 배치된 개행 문자를 제거할 수 있습니다. 제 생각에는 스크립트를 다음과 같이 다시 작성해야 할 것 같습니다.

cat test01 | awk '{for (i = 1; i <= NF; i++){printf $i"'\'','\''"}; printf "\n";}'

답변4

내 시도는 다음과 같습니다 ...

내 명령문은 cat, awk, sed의 세 부분으로 구성됩니다.

awk 및 sed 문은 확실히 개선될 수 있지만 아직 배우는 중입니다. test01을 test2.txt로 변경했습니다.

cat test2.txt | awk -F "\\t| " 'BEGIN {ORS=""}{print "("}{ORS=","}{for (i = 1; i <= NF; i++){print "'\''"$i"'\''"}}{print ")\n"}{ORS=""}' | sed 's/,)/),/' | sed 's/^,//' | sed '$ s/),/);/'

관련 정보