\r\n
대부분의 답변은 파일 삭제에 관한 것이기 때문에 이 질문을 어떻게 표현해야 할지 잘 모르겠습니다 .
독특한 문제가 있습니다. 압축 파일에 무작위로 번호가 매겨져 있으며 이를 데이터베이스 레코드와 올바르게 연결하려면 파일 내용을 나열하고 검사해야 합니다.
이 솔루션을 사용하고 있습니다 "Bash 스크립트에서 한 줄씩 stdout을 캡처하는 방법"
이것은 좋은 시작입니다.
일부 콘텐츠에는 공백이 포함된 이름이 있습니다. 다음 해결책을 찾았습니다. 세 번째 열을 마지막 열까지 인쇄하는 방법은 무엇입니까?
데이터베이스 레코드를 업데이트하려고 할 때 레코드가 ^M
파이프라인 결과에 삽입되었지만 열에 awk
만 삽입되는 것을 발견했습니다 NF
.
이 특정 결함을 해결하는 방법을 잘 모르겠습니다. 어디에 ^M
삽입해야 할지, 마지막 열에서 어떻게 제거해야 할지 모르겠습니다 .
내 코드
이 줄을 제거하면 제대로 작동합니다.^M
filename="$(echo "$line" | awk '{if ($3 ~ /^M$/) {sub(/^M$/,"", $3)} printf $3; printf ""}')"
이 줄은 실패합니다.
text="$(echo "$line" | awk '{for(i=6;i<NF+1;i++) {if ($i ~ /^M$/) {sub(/^M$/,"", $i)} } printf "%s ", $i; printf ""}')"
단순화된 버전은 실패합니다.
text="$(echo "$line" | awk '{for(i=6;i<NF+1;i++) sub(/^M$/,"", $i) printf "%s ", $i; printf ""}')"
vim
/ 에서 사용하여 생성하는 것은 vi
^M
효과가 없습니다.ctrl-V + <return key>
\r\n
저는 을 사용하고 있고 cygwin
, 오랫동안 사용해 왔으며 *nix
잘 작동하는 다른 스크립트를 작성했습니다. 어떤 이유로 이 특정 실행이 출력에 awk
추가되는 것을 발견했습니다.^M
내가 찾은이 문제비슷한 질문이 있었지만 vim
처음부터 스크립트를 작성했기 때문에 Windows 기반 편집기가 포함되지 않았습니다.
해당 Windows 폴더를 삼바 공유로 마운트하고 Linux에서 스크립트를 실행하면 출력이 생성되지 않으므로 ^M
이 시점에서 이것이 버그인지 아니면 다른 문제인지 궁금합니다. 정말 이상해요.
고쳐 쓰다 sub()에서 REGEX를 사용하면 문자열이 비어 있게 반환되므로 CRLF를 지우는 방법을 올바르게 이해하지 못했습니다.
NF+1은 i<=NF를 사용하여 CRLF의 도입을 찾으려는 이전 시도의 잔재입니다.
답변1
awk
GNU awk
및 mawk
busybox(이 3개는 Linux 기반 시스템에서 일반적이며 awk
Cygwin의 기본값은 GNU라고 생각합니다)를 포함한 일부 구현을 사용하면 입력 레코드 구분 기호가 POSIX의 단일 문자가 아닌 정규식이 될 수 있습니다.awk
RS
그 중에서 다음을 수행할 수 있습니다.
awk -v RS='\r\n' '{print $NF}' < your-file.msdos
다음 파일을 처리하거나 다음을 수행합니다.
awk -v RS='\r?\n' '{print $NF}' < your-file.msdos-or-unix
\n
구분 기호 또는 구분 기호를 사용하여 \r\n
두 파일을 모두 처리하는 기능.
일부 MS-DOS 파일은 구분 기호가 없는 마지막 줄을 선호하지만 이는 awk
인쇄할 때 출력 레코드 구분 기호(여기에 ORS
남아 있음 \n
)를 모든 레코드에 추가하므로 출력에서도 이 문제를 수정합니다.
또한 기본 필드 분할 측면에서 awk
구현 간의 차이점을 확인할 수 있습니다 . POSIX에서는 시퀀스로 분할해야 한다고 말합니다.공백, 선행 및 후행을 제거합니다. 개념공백로캘에 따라 다르며 최소한 SPC 및 TAB을 포함합니다. 많은 awk
구현에서는 이를 로케일에 관계없이 SPC 및 TAB으로만 제한하고 NL도 추가합니다(레코드 구분 기호가 줄 바꿈이 아닌 경우에만 관련됨).
busybox
awk에는 모든 ASCII 공백이 포함되어 있으므로 CR
, FF
. VT
따라서 busybox에서는 awk
필드에 기본적으로 CR이 포함되지 않습니다. 필드를 공백이 아닌 시퀀스로 정의하여 awk
GNU 를 사용하여 동일한 동작을 달성할 수 있습니다 .gawk -v 'FPAT=[^[:space:]]'
추가 참고사항:
- 텍스트를 처리하는 쉘 루프 방지, 특히 여기서는 이미 사용하고 있으므로
awk
텍스트 작업에 적합한 도구 중 하나입니다. echo
임의의 데이터 와 함께 사용하지 마십시오- 첫 번째 매개변수
printf
는 형식이며, 거기에서 임의의 데이터를 사용하고 싶지 않습니다. 추가하지 않고 인쇄printf "%s", $3
하려면 대신 를 사용하세요 .$3
ORS
printf $3
printf ""
작동하지 않습니다. 효과가 없습니다. 개행 문자를 인쇄하려면printf "\n"
또는 를 사용하십시오print ""
(후자는ORS
기본적으로 개행 문자를 인쇄합니다).
답변2
awk
리터럴 의미 는 인식되지 않지만 ^M
CRLF 패턴으로 인식되므로 아래와 같이 CR 문자 표현을 직접 사용할 수 있습니다 \r\n
. sub()
또한 필드에 문자가 포함되어 있는지 확인하고 바꿀 필요가 없습니다. 위의 패턴을 찾을 수 없으면 대체 함수는 아무 작업도 수행하지 않습니다. 따라서 마지막 열의 CR을 다음으로 바꾸면 됩니다.
awk '{ sub("\r", "", $NF); print $NF }'
여러 컬럼을 교체해야 하는 경우 $NF
필요한 적절한 컬럼으로 전환하십시오.
파일 끝까지 모든 열에 대해 루프에서 이 작업을 수행하는 경우 다음을 수행하십시오.
awk '{ for(i=6; i<=NF ; i++) { sub("\r", "", $i); printf "%s ", $i; } }'
또한 파일에는 가장 큰 NF
열만 포함될 수 있으며 이것이 $NF
마지막 열 값입니다. NF
마지막 열 값에 액세스할 때까지 실행되도록 루프를 변경합니다 .