열의 텍스트를 바꾸는 방법

열의 텍스트를 바꾸는 방법

아래와 같이 데이터가 포함된 대용량 파일(2GB 이상)이 있습니다.

12,324,32342,E:fsdsf,23432,34534,45345,324

13,3224,342,E:werwefsdsf,23432,34534,45345,324

121,3244,33442,E:,23432,34534,45345,324

E:여기에서는 네 번째 열에서 공백이 발견되는 모든 위치를 바꿔야 ""하지만 나중에 문자열을 찾을 때마다 E:그대로 유지되어야 합니다.

예상되는 출력은 다음과 같습니다.

12,324,32342,E:fsdsf,23432,34534,45345,324

13,3224,342,E:werwefsdsf,23432,34534,45345,324

121,3244,33442,,23432,34534,45345,324

답변1

귀하의 구문은거의옳은. 에서 문자열 동일성을 테스트하려면 awk이중 등호를 사용하십시오: ==. 도착하다값을 지정하다, 단일 등호를 사용합니다.

따라서 이것을 사용하면 if ($4 == "E:")원하는 결과를 얻을 수 있습니다.

전체 명령은 다음과 같습니다. 사용한 명령과 문자 차이가 하나뿐이라는 점에 유의하세요. 이것이 유일한 실수입니다.

awk -F , '{ if ($4 == "E:") $4="";}1' OFS=, data.final

몇 가지 다른 구문과 다른 접근 방식을 보여주기 위해 다음 버전은 완전히 동일합니다.

awk -F, -v OFS=, '$4 == "E:" { $4 = "" }; 1' data.final

awk 'BEGIN { FS=OFS="," }; $4 == "E:" { $4 = "" }; {print}' data.final

awk -F, -v OFS=, '{sub( /^E:$/, "", $4); print}' data.final

위 사항에 대한 참고사항:

  1. 전체 코드 블록이 단지 if/then인 경우 조건을 코드 블록의 필터로 사용할 수 있습니다. 따라서 다음 $4 == "E:" {$4 = ""}과 완전히 동일합니다.{if ($4 == "E:") {$4 = ""}}
  2. "then" 문이 하나만 있는 경우에도 코드 블록에 "then" 문을 포함하는 것이 좋습니다 if ($4 == "E:") {$4 = ""}.if ($4 == "E:") $4 = "";
  3. -F값 세트는 첫 번째 파일의 첫 번째 줄을 고려하기 전에 모든 변수의 값을 설정하는 데 사용될 FS수 있습니다. (아마도 알고 계실 것입니다.) 블록을 사용하여 동일한 작업을 수행할 수도 있습니다. 스크립트가 자체 포함되기를 원할 때 이 점을 알아두는 것이 좋습니다.-vawkBEGINawk
  4. 1line in을 인쇄하는 이유는 항상 true로 평가되는 조건(필터)이고, 필터에 코드 블록이 첨부되지 않은 경우 기본 동작은 awkto 이기 때문입니다. 따라서 그 자체로는 or 또는 just와 동일합니다.awkprint $011 {print}1 {print $0}{print}
  5. sub마지막 변형에서는 정규식(문자열의 시작, 문자열의 끝)을 in 으로 바꾸는 함수를 사용했습니다 ./^E:$/E:""$4

sub함수는 대체된 횟수(1 또는 0, 여러 대체를 만드는 경우)를 반환 하므로 함수 결과에 1을 추가하여 항상 참인 패턴이 있는지 확인하여 교체가 인쇄되는지 여부를 확인하여 이 문제를 해결할 gsub수 있습니다. sub결과 라인. 다음은 골프 버전의 코드입니다. 나중에 유지 관리할 스크립트에 코드를 넣는 경우 초보자에게는 권장되지 않습니다.

awk -F, -v OFS=, 'sub(/^E:$/,"",$4)+1' data.final

:)

답변2

그리고 sed:

sed -r 's/^([^,]+,[^,]+,[^ ]+,)E:(,)/\1\2/' file.txt

쉼표로 구분된 네 번째 필드에 다음 항목만 포함된 경우 해당 필드는 비어 있습니다 E:.

예:

% cat file.txt
12,324,32342,E:fsdsf,23432,34534,45345,324
13,3224,342,E:werwefsdsf,23432,34534,45345,324
121,3244,33442,E:,23432,34534,45345,324

% sed -r 's/^([^,]+,[^,]+,[^ ]+,)E:(,)/\1\2/' file.txt 
12,324,32342,E:fsdsf,23432,34534,45345,324
13,3224,342,E:werwefsdsf,23432,34534,45345,324
121,3244,33442,,23432,34534,45345,324

답변3

파일 이름이 이라고 가정하면 file다음을 시도해 볼 수 있습니다.

while read -r line; 
do 
var="$(echo "$line" | cut -d ',' -f 4)";

  if [[ "$var" = "E:" ]]; then echo "$line" | sed s/"$var"/''/g ; 
  else echo "$line";
  fi; 

done < file

또는:

while read -r line; do var="$(echo "$line" | cut -d ',' -f 4)"; if [[ "$var" = "E:" ]]; then echo "$line" | sed s/"$var"/''/g ; else echo "$line";fi; done < file

설명하다:

  1. while read -r line;파일을 한 줄씩 읽기
  2. var="$(echo "$line" | cut -d ',' -f 4)";4번째 위치의 문자열을 ,변수로 분리합니다.var
  3. if [[ && "$var" = "E:" ]]; then echo "$line" | sed s/"$var"/' '/g ;$var문자열이 있으면 공백 으로 바꿉니다 E:.sed s/"$var"/''/g ;""
  4. else echo "$line";그렇지 않으면 행을 그대로 인쇄합니다.

산출(질문에서 예상한 대로):

  • file:

    $ cat file
    12,324,32342,E:fsdsf,23432,34534,45345,324
    
    13,3224,342,E:werwefsdsf,23432,34534,45345,324
    
    121,3244,33442,E:,23432,34534,45345,324
    
  • 실행 명령:

    $ while read -r line; do var="$(echo "$line" | cut -d ',' -f 4)"; if [[ "$var" = "E:" ]]; then echo "$line" |sed s/"$var"/' '/g ; else echo "$line";fi; done < file
    12,324,32342,E:fsdsf,23432,34534,45345,324
    
    13,3224,342,E:werwefsdsf,23432,34534,45345,324
    
    121,3244,33442,,23432,34534,45345,324
    

>> file2|tee file2명령 끝에서 또는 를 사용하여 출력을 파일로 리디렉션 할 수도 있습니다 .

while read -r line; do var="$(echo "$line" | cut -d ',' -f 4)"; if [[ "$var" = "E:" ]]; then echo "$line" |sed s/"$var"/' '/g ; else echo "$line";fi; done < file | tee file2

관련 정보