파일에서 특수 문자를 제거하고 필드 구분 기호를 유지합니다.

파일에서 특수 문자를 제거하고 필드 구분 기호를 유지합니다.

고정 길이 파일의 첫 번째 열에 있는 모든 특수 문자를 제거할 수 있었지만 결과적으로 모든 후속 열은 제거된 문자 수만큼 왼쪽으로 이동하게 됩니다. 공백으로 구분된 파일입니다. 입력 파일의 라인 1이 손상되었습니다. 2호선은 다음과 같아야 합니다. 문자열 000022000362700은 두 줄 모두에서 49번째 위치에서 시작됩니다. 내가 겪고 있는 문제는 3개의 특수 문자를 제거한 후 필드가 위치 46으로 이동한다는 것입니다.

GAVISCON 리퀴드 민트 000022000362700 159588000007979400 50001584182 0006S020000
GAVISCON 리퀴드 민트 OT 000022000362700 159588000007979400 50001584182 0006S020000

내가 사용하는 명령은 다음과 같습니다.

cat file.txt | grep '[^ - ~]' | sed's/[^ - ~]//g'

그러면 다음과 같은 출력이 생성됩니다.

    GAVISCON LIQUID PEPPERMINT OT        000022000362700   159588000007979400  50001584182        0006S020000

특수 문자를 제거함으로써 변경된 필드의 오른쪽에 있는 각 필드가 왼쪽으로 이동되어 필드 시작 위치가 변경되었습니다.

한동안 검색해 보았지만 이 문제에 대한 해결책을 찾을 수 없습니다.

어떻게 진행해야 하나요?

답변1

다음 명령을 사용하십시오.

sed -r 's/(\^|-|~)/ /g' file.txt
  • sed -r

    -r, --regexp-extended
    스크립트에서 확장 정규식을 사용합니다.

  • / /필드 구분 기호로 사용되는 공백(또는 기타 문자열)

  • (\^|-|~)

    • 첫 번째 캡처 그룹(\^|-|~)

      • 첫 번째 옵션:\^

        \^^리터럴 일치 문자

      • 두 번째 옵션:-

        --리터럴 일치 문자

      • 세 번째 옵션:~

        ~~리터럴 일치 문자

또 다른 변형은 이것입니다(감사합니다@코스타스):

sed 's/[-~^]/ /g' file.txt
  • [^-~]

    • [-~^]아래 목록에 있는 단일 문자와 일치합니다.

      -~^목록의 단일 -~^문자

답변2

sed's/[^ - ~]//g'잘못된 명령에 대해서만 불평하므로 사용한 명령이 아닐 수도 있습니다. 항상 복사해서 붙여넣으세요!

아무래도 도망친 것 같군요 sed 's/[^ -~]//g'. 이는 인쇄 가능한 ASCII 문자가 아닌 모든 문자를 빈 문자열로 대체합니다. 즉, 인쇄할 수 없는 모든 ASCII 문자가 제거됩니다. (이것은 기본 로케일, 즉 아래에 해당되지만 LC_ALL=C다른 많은 로케일에서는 해당되지 않습니다.)

열 정렬을 유지하려면 인쇄할 수 없는 각 문자를 공백으로 바꾸십시오.

sed 's/[^ -~]/ /g'

명령 으로 인해 grep인쇄할 수 없는 문자가 포함된 줄만 출력에 나타납니다. 그럴 필요는 없습니다 grep. 수정이 필요하지 않은 줄 sed은 출력의 올바른 위치에 나타납니다.

<file.txt LC_ALL=C sed 's/[^ -~]/ /g' >new-file.txt

이렇게 하면 열 중간에 공백이 추가됩니다. 예를 들어 다음과 같이 됩니다.

GAVISCON LIQUID PEPPERMINT    OT        000022000362700   159588000007979400  50001584182        0006S020000

공백이 열의 오른쪽에서 끝나도록 하려면 다음과 같이 하십시오.

GAVISCON LIQUID PEPPERMINT OT           000022000362700   159588000007979400  50001584182        0006S020000

기둥이 멈춰야 하는 위치를 나타내는 다른 접근 방식이 필요합니다. 이 작업은 sed에서도 가능하지만 awk에서는 훨씬 쉽습니다. 첫 번째 열에서 인쇄할 수 없는 문자를 제거하고 위치 49부터 시작하는 다른 열의 데이터를 유지하는 방법은 다음과 같습니다.

<file.txt LC_ALL=C awk '{
    first_column = substr($0, 1, 48);
    gsub(/[^ -~]/, "", first_column);
    printf "%-48s%s\n", first_column, substr($0, 49)
}' >new-file.txt

관련 정보