Sign up ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. It's 100% free, no registration required.

I need to periodically run a command, that ensures that some text files are kept in linux mode. Unfortunately dos2unix always modifies file, which would mess file's and folder's timestamp and cause unnecessary writes.

The script I write is in Bash, so I'd prefer answers based on Bash.

share|improve this question

8 Answers 8

You can use dos2unix as a filter and compare its output to the original file:

dos2unix < test | cmp -s - test
share|improve this answer
Very smart and useful, because it tests the complete file and not only the first or a few line. – halloleo May 19 at 0:04

If the goal is just to avoid affecting the timestamp, dos2unix has a -k or --keepdate option which will keep the timestamp the same. It will still have to do a write to make the temporary file and rename it, but your timestamps will not be affected.

If any modification of the file is unacceptable, you can use the following solution from this answer.

find . -not -type d -exec file "{}" ";" | grep CRLF
share|improve this answer

You could try to grep for CRLF code, octal:

grep -U $'\015' myfile.txt

or hex:

grep -U $'\x0D' myfile.txt
share|improve this answer
Of course, the assumption is that this is a text file. – mdpc Jun 17 '13 at 17:24
I like this grep usage because it allows me to easily list all such files in the directory with grep -lU $'\x0D' * and pass the output to xargs. – Melebius Apr 30 at 6:19

First method:

[[ $(grep -c $'\r\n' myfile.txt) -gt 0 ]] && echo dos

(We test if there is a carriage return in the file.)

Second method:

[[ $(file myfile.txt) =~ CRLF ]] && echo dos

because file reports something like:

myfile.txt: UTF-8 Unicode text, with CRLF line terminators
share|improve this answer
You can replace "$(echo -e '\r')" with the much simpler $'\r', although personally I'd use $'\r\n' to reduce the number of false positives. – rici Jun 17 '13 at 17:03
@rici grep $'\r\n' seems to match all files on my system... – depquid Jun 17 '13 at 17:09
@rici: good catch. I edited my answer according to your suggestion. — depquid: Maybe you are on Windows? :-) rici's tip works here. – BertS Jun 17 '13 at 17:11
@depquid (and BertS): Actually, I think the correct invocation is grep -U $'\r$', to prevent grep trying to second-guess line-endings. – rici Jun 17 '13 at 17:18
Also, you can use -q to just set the return code if a match is found, instead of -c which requires an additional check. Personally I like your second solution, although it's highly dependent on the whims of file and might not work in a non-English locale. – rici Jun 17 '13 at 17:22

a bash function for you:

# return 0 (true) if first line ends in CR
isDosFile() {
    [[ $(head -1 "$1") == *$'\r' ]]  

Then you can do stuff like

streamFile () {
    if isDosFile /tmp/foo.txt; then
        sed 's/\r$//' "$1"
        cat "$1"

streamFile /tmp/foo.txt | process_lines_without_CR
share|improve this answer
You don't have to use isDosFile() in your example: streamFile() { sed 's/\r$//' "$1" ; }. – Evan Teitelman Jun 17 '13 at 18:59
I think this is the most elegant solution; it doesn't read whole file, just the first line. – Adam Ryczkowski Jun 22 '13 at 20:50

If a file has DOS/Windows-style CR-LF line endings, then if you look at it using a Unix-based tool you'll see CR (`'\r') characters at the end of each line.

This command:

grep -l '^M$' filename

will print filename if the file contains one or more lines with Windows-style line endings, and will print nothing if it doesn't. Except that the "^M" has to be a literal carriage return character, typically entered in the shell by typing Ctl-V Enter. Unfortunately, I can't find a way to encode a literal carriage return (or other control character) in a grep regular expression other than entering it directly.

You can you another tool instead:

awk '/\r$/ { exit(1) }' filename

This will exit with a status of 1 (setting $? to 1) if the file contains any Windows-style line endings, and with a status of 0 if it doesn't, making it useful in a shell if statement (note the lack of [ brackets ]):

if awk '/\r$/ { exit(1) }' filename ; then
    echo filename has Unix-style line endings
    echo filename has at least one Windows-style line ending

A file can contain a mixture of Unix-style and Windows-style line endings. I'm assuming here that you want to detect files that have any Windows-style line endings.

share|improve this answer

If you only want to test whether the file is crlf or lf, just try:

sed -n l <scriptname>


How does it work? From sed manpage, you can see:

-n : Suppresses default output
 l : list nonprinting characters

So using l will print nonprinting characters like crlf, lf,... and -n will remove line that is regular output of sed, which doesn't contain the nonprinting characters.

share|improve this answer
How does this work? – lgeorget Jun 17 '13 at 17:36
That will find any nonprinting characters, not just CR characters at the end of a line. And it doesn't tell you whether such characters exist or not, it just displays them as \r. – Keith Thompson Jun 17 '13 at 18:53

Since version 7.1 dos2unix has an -i, --info option to get information about line breaks. You can use dos2unix itself to test which files need conversion.


dos2unix -ic *.txt | xargs dos2unix
share|improve this answer
Here is link to the changelog itself – Adam Ryczkowski Sep 23 at 14:16

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.