일부 텍스트 파일이 Linux 모드로 유지 되도록하는 명령을 정기적으로 실행해야 합니다. 불행히도 dos2unix
항상 파일을 수정하면 파일과 폴더의 타임 스탬프가 엉망이되어 불필요한 쓰기가 발생합니다.
내가 작성한 스크립트는 Bash에 있으므로 Bash를 기반으로 한 답변을 선호합니다.
일부 텍스트 파일이 Linux 모드로 유지 되도록하는 명령을 정기적으로 실행해야 합니다. 불행히도 dos2unix
항상 파일을 수정하면 파일과 폴더의 타임 스탬프가 엉망이되어 불필요한 쓰기가 발생합니다.
내가 작성한 스크립트는 Bash에 있으므로 Bash를 기반으로 한 답변을 선호합니다.
답변:
dos2unix
필터로 사용 하고 출력을 원본 파일과 비교할 수 있습니다 .
dos2unix < myfile.txt | cmp -s - myfile.txt
test
에 의한 myfile.txt
혼동을 피하기 위해 귀하의 예를 두 번 /usr/bin/test
.
-s
출력을 보려면 플래그를 삭제해야합니다 . 매뉴얼 페이지에서 : -s, --quiet, --silent suppress all normal output
목표가 타임 스탬프에 영향을 미치지 않도록하려면 타임 스탬프를 동일하게 유지 dos2unix
하는 -k
또는 --keepdate
옵션이 있습니다. 임시 파일을 작성하고 이름을 바꾸려면 여전히 쓰기 작업을 수행해야하지만 타임 스탬프에는 영향을 미치지 않습니다.
파일 수정이 허용되지 않는 경우이 답변 에서 다음 솔루션을 사용할 수 있습니다 .
find . -not -type d -exec file "{}" ";" | grep CRLF
find ... -exec file ... | grep CRLF
DOS 라인 엔딩의 파일 (예 : 바이트 0D 0A)은 "당신에게 뭔가를 얻을 것이다 : ./1/dos1.txt: ASCII text, with CRLF line terminators
당신이 실제 문자열 CRLF를 포함하므로 일치한다 볼 수 있듯이 grep
을 찾고 간단한 문자열 CRLF
grep
CRLF 코드, 8 진수를 시도 할 수 있습니다 .
grep -U $'\015' myfile.txt
또는 16 진수 :
grep -U $'\x0D' myfile.txt
grep
사용법은 디렉토리에있는 모든 파일을 쉽게 나열 grep -lU $'\x0D' *
하고 출력을 전달할 수 있기 때문에 좋아 합니다 xargs
.
버전 이후 7.1
DOS2UNIX가있다 -i
, --info
옵션은 줄 바꿈에 대한 정보를 얻을 수 있습니다. dos2unix 자체를 사용하여 변환이 필요한 파일을 테스트 할 수 있습니다.
예:
dos2unix -ic *.txt | xargs dos2unix
grep
) :캐리지 리턴이 포함 된 행을 계산하십시오.
[[ $(grep -c $'\r' myfile.txt) -gt 0 ]] && echo dos
캐리지 리턴으로 끝나는 줄을 세십시오 .
[[ $(grep -c $'\r$' myfile.txt) -gt 0 ]] && echo dos
이들은 일반적으로 동일합니다. 라인 내부 (즉, 끝이 아님)의 캐리지 리턴은 드물다.
보다 효율적인 :
grep -q $'\r' myfile.txt && echo dos
이것은 더 효율적입니다
grep -c
패턴의 모든 발생을 계산하기 위해 전체 파일을 읽어야 하기 때문에 패턴 grep -q
의 첫 번째 발생을보고 종료 할 수 있습니다.노트:
-U
옵션 을 추가해야 할 수도 있습니다 (예 : use -cU
또는 -qU
) grep
. 파일이 텍스트라고 생각하면 $
정규 표현식이 "정확하게"작동 하도록하기 위해 행 끝에있는 캐리지 리턴을 무시 합니다. 정규 표현식이 \r$
! -U
(또는 --binary
)을 지정 하면이 추측이 우선 적용 grep
되어 파일을 이진 파일로 취급하고 CR 끝이 그대로있는 상태로 데이터를 일치하는 메커니즘으로 그대로 전달합니다.grep … $'\r\n' myfile.txt
되므로 하지 마십시오 . 그냥 같이 포함 된 줄을 찾습니다 또는 널 (null) 문자열,
포함하는 라인을 찾습니다 또는 널 (null) 문자열, 모든 라인은 널 (null) 문자열과 일치합니다.grep
\n
grep -E 'foo|'
foo
grep $'\r\n'
\r
file
) :[[ $(file myfile.txt) =~ CRLF ]] && echo dos
file
다음과 같은 보고서가 있기 때문입니다 .
myfile.txt: UTF-8 Unicode text, with CRLF line terminators
보다 안전한 변형 :
[[ $(file -b - < myfile.txt) =~ CRLF ]] && echo dos
어디
file -b
파일 이름이 아닌 파일 형식 만 출력합니다. 이 없다면, 파일 그 이름 문자가 포함 된CRLF
가양 발생하게됩니다.file - < filename
로 filename
시작 하더라도 작동합니다 -
.
Bash 스크립트 : 파일이 텍스트 파일인지 확인을 참조하십시오 .file
영어 이외의 로케일 에서는 출력을 확인 하지 못할 수 있습니다.
"$(echo -e '\r')"
훨씬 더 간단한 것으로 바꿀 수 있습니다 . $'\r'
$'\r\n'
grep $'\r\n'
는 내 시스템의 모든 파일과 일치하는 것 같습니다.
grep -U $'\r$'
방지하기 위해, grep
두 번째 추측 라인 엔딩하려고합니다.
-q
대신 일치하는 것이 있으면 리턴 코드를 설정하는 데 사용할 수 있습니다 -c
. 개인적으로 나는 당신의 두 번째 솔루션을 좋아하지만, file
영어가 아닌 로케일 에서는 변덕스럽고 작동하지 않을 수도 있습니다.
사용하다 cat -A
$ cat file
hello
hello
이제이 파일이 * NIX 시스템에서 작성된 경우 표시됩니다.
$ cat -A file
hello$
hello$
그러나이 파일이 Windows에서 만들어진 경우 표시됩니다
$ cat -A file
hello^M$
hello
^M
대표 CR
및 $
대표 LF
. Windows는 마지막 줄을 저장하지 않았습니다.CRLF
파일 내용도 변경되지 않습니다.
-A
고양이에. cat -A file | less
파일이 너무 큰 경우 한 가지 팁을 사용 하는 것 입니다. 특히 긴 파일의 파일 끝을 확인하는 것이 드문 일이 아니라고 확신합니다. ( q
당신을위한 bash 함수 :
# return 0 (true) if first line ends in CR
isDosFile() {
[[ $(head -1 "$1") == *$'\r' ]]
}
그럼 당신은 같은 일을 할 수 있습니다
streamFile () {
if isDosFile /tmp/foo.txt; then
sed 's/\r$//' "$1"
else
cat "$1"
fi
}
streamFile /tmp/foo.txt | process_lines_without_CR
파일에 DOS / Windows 스타일의 CR-LF 줄 끝이 있으면 Unix 기반 도구를 사용하여 볼 경우 각 줄 끝에 CR ( '\ r') 문자가 표시됩니다.
이 명령은
grep -l '^M$' filename
인쇄 할 filename
파일이 Windows 스타일의 라인 엔딩 하나 이상의 라인이 포함 된 경우와 그렇지 않은 경우 아무 것도 인쇄되지 않습니다. ^M
문자 그대로 캐리지 리턴 문자 여야 한다는 점을 제외하고는 일반적으로 Ctrl+ V다음에 Enter
(또는 Ctrl+ V와 Ctrl+ M) 를 입력하여 터미널에 입력 합니다. bash 쉘을 사용하면 리터럴 캐리지 리턴을 $'\r'
( here 문서화 됨 )로 작성할 수 있으므로 다음과 같이 작성할 수 있습니다.
grep -l $'\r$' filename
다른 쉘도 비슷한 기능을 제공 할 수 있습니다.
대신 다른 도구를 사용할 수 있습니다.
awk '/\r$/ { exit(1) }' filename
이 상태로 종료됩니다 1
(설정 $?
에 1
파일이 모든 Windows 스타일의 라인 엔딩을 포함하고, 상태에있는 경우) 0
는 쉘에서 유용하게하지 않는 경우 if
문 (의 부족주의 [
브래킷 ]
) :
if awk '/\r$/ { exit(1) }' filename ; then
echo filename has Unix-style line endings
else
echo filename has at least one Windows-style line ending
fi
파일에는 Unix 스타일과 Windows 스타일 줄 끝이 혼합되어 포함될 수 있습니다. 여기서는 Windows 스타일 줄 끝 이 있는 파일을 감지하려고한다고 가정합니다 .
$'\r'
이 질문에 대한 다른 답변에서 언급 했듯이을 입력하여 bash (및 다른 쉘)의 명령 줄에서 캐리지 리턴을 인코딩 할 수 있습니다 .