sed를 사용하여 대용량 파일의 텍스트 바꾸기

sed를 사용하여 대용량 파일의 텍스트 바꾸기

전달된 정규식을 기반으로 대체될 텍스트가 포함된 대용량 파일이 있습니다. 정규식을 테스트하여 일치하는 패턴을 찾을 수 있지만 이를 사용할 때 sed대체 텍스트가 없습니다. 참고로 제 환경은 Windows 16GB 메모리이고 파일 크기는 14GB 정도 되는 점 참고해주세요.

sed -i "/,[\r\n]+  CONSTRAINT `[a-zA-Z0-9_]+` FOREIGN KEY \(`[a-zA-Z0-9_]+`\) REFERENCES `[a-zA-Z0-9_]+` \(`[a-zA-Z0-9_]+`\)/ s// /g" all_files_test.sql

cmd.exe(위 내용은 Unix 셸이 아닌 명령줄 이라는 점에 유의하세요 .)

all_files_test.sql문서:

DROP TABLE IF EXISTS `holdings_FLZWHX`;
;
;
CREATE TABLE `holdings_FLZWHX` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `DateAdded` datetime NOT NULL,
  `FundId` int(11) NOT NULL,
  `AssetId` int(11) NOT NULL,
  `DayChangeEqt` decimal(18,2) DEFAULT NULL,
  `PMinDayRet` decimal(18,2) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `holdings_FLZWHX_FundId` (`FundId`),
  KEY `holdings_FLZWHX_AssetId` (`AssetId`),
  KEY `holdings_FLZWHX_TypeId` (`TypeId`),
  KEY `holdings_FLZWHX_TickerId` (`TickerId`),
  KEY `holdings_FLZWHX_StyleId` (`StyleId`),
  KEY `holdings_FLZWHX_SectorId` (`SectorId`),
  KEY `holdings_FLZWHX_CountryId` (`CountryId`),
  KEY `holdings_FLZWHX_CurrencyId` (`CurrencyId`),
  CONSTRAINT `holdings_FLZWHX_ibfk_1` FOREIGN KEY (`FundId`) REFERENCES `target_funds` (`fundid`),
  CONSTRAINT `holdings_FLZWHX_ibfk_2` FOREIGN KEY (`AssetId`) REFERENCES `asset` (`id`),
  CONSTRAINT `holdings_FLZWHX_ibfk_3` FOREIGN KEY (`TypeId`) REFERENCES `type` (`id`),
  CONSTRAINT `holdings_FLZWHX_ibfk_4` FOREIGN KEY (`TickerId`) REFERENCES `ticker` (`id`),
  CONSTRAINT `holdings_FLZWHX_ibfk_5` FOREIGN KEY (`StyleId`) REFERENCES `style` (`id`),
  CONSTRAINT `holdings_FLZWHX_ibfk_6` FOREIGN KEY (`SectorId`) REFERENCES `sector` (`id`),
  CONSTRAINT `holdings_FLZWHX_ibfk_7` FOREIGN KEY (`CountryId`) REFERENCES `country` (`id`),
  CONSTRAINT `holdings_FLZWHX_ibfk_8` FOREIGN KEY (`CurrencyId`) REFERENCES `currency` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4201 DEFAULT CHARSET=latin1;
;

내가 기대하는 결과는 다음과 같습니다.

DROP TABLE IF EXISTS `holdings_FLZWHX`;
;
;
CREATE TABLE `holdings_FLZWHX` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `DateAdded` datetime NOT NULL,
  `FundId` int(11) NOT NULL,
  `AssetId` int(11) NOT NULL,
  `DayChangeEqt` decimal(18,2) DEFAULT NULL,
  `PMinDayRet` decimal(18,2) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4201 DEFAULT CHARSET=latin1;
;

답변1

  1. 테스트된 정규식기본 및 확장 정규식뿐만 아니라 비표준 스타일도 많고 그 중 일부를 사용하고 있기 때문에 어려운 설명입니다.

  2. sed확장 정규식을 사용하고 있습니다. with 옵션을 알려주어야 합니다.-E

  3. 패턴에서 줄 바꿈(캐리지 리턴, 줄 바꿈)을 찾고 있지만 sed입력을 한 줄씩 처리하므로 줄을 연결하지 않으면 일치하지 않습니다. 그러나 귀하는 GNU를 사용하고 있는 것으로 나타나 므로 모든 라인을 한 번에 처리할 수 있는 옵션이 sed있습니다 . -z이는 예제에서는 작동하지만 대용량 파일에서는 실패할 수 있습니다.

  4. 쉘에 따라 스크립트를 보호하기 위해 큰따옴표 대신 작은따옴표를 사용해야 할 수도 있습니다.

    sed -zEi '/,[\r\n]+ 제약 조건 [a-zA-Z0-9_]+외래 키( [a-zA-Z0-9_]+) 참조 [a-zA-Z0-9_]+( [a-zA-Z0-9_]+)/ s// /g' all_files_test.sql

당신이 예상한 대체 작업을 수행했으며 zsh아마도 당신의 작업도 수행했을 수도 있습니다 cmd.exe. 여전히 행 주소는 버퍼의 모든 행에 대해 의미가 없습니다.

sed -zEi 's/,[\r\n]+  CONSTRAINT `[a-zA-Z0-9_]+` FOREIGN KEY \(`[a-zA-Z0-9_]+`\) REFERENCES `[a-zA-Z0-9_]+` \(`[a-zA-Z0-9_]+`\)/ /g' all_files_test.sql

더 논리적입니다(결과는 동일하게 유지됨). 마지막으로 선이 어떻게 KEY `holding사라지기를 원하는지 설명하지 않았습니다 .

그러나 이제 여러 줄 바꾸기를 수행하는 표준 방법이 있으며 이 N;P;D패턴은 대용량 파일에도 작동합니다.

sed -Ei 'N;/,*[\r\n]+  CONSTRAINT `[a-zA-Z0-9_]+` FOREIGN KEY \(`[a-zA-Z0-9_]+`\) REFERENCES `[a-zA-Z0-9_]+` \(`[a-zA-Z0-9_]+`\)/{s// /g;s/^/\n/;D;};P;D' all_files_test.sql

N패턴이 일치할 수 있도록 항상 다음 줄을 추가하세요. P버퍼의 첫 번째 줄을 인쇄하고 D첫 번째 줄을 삭제하고 나머지 줄부터 다시 시작하세요. 따라서 N;P;D패턴 공간에는 항상 한 쌍의 선이 있습니다.

그러나 교체하는 경우 한 줄만 있지만 다음 줄을 계속하고 싶으므로 패턴 시작 부분에 빈 줄 s/^/\n/( GNU에만 해당!)을 삽입하여 로 교체되도록 하는 것이 요령입니다 .sedD

관련 정보