We have several thousand large (10M<lines) text files produced by a windows machine.
We need to change the file encoding of these files from cp1252
to utf-8
, replace any bare Unix LF sequences (i.e. \n
) with spaces, then replace the DOS line end sequences ("CR-LF", i.e \r\n
) with Unix line end sequences (i.e. \n
).
The dos2unix
utility is not available for this task.
We've written a bash function to package these operations together using iconv
and sed
, with iconv
doing the encoding and sed
dealing with the LF/CRLF sequences.
It first changes the encoding, then replaces \r\n
sequences with a placeholder. It then replaces remaining \n
with
, and finally replaces the placeholders with \n
:
post_extract() {
iconv --from-code=CP1252 --to-code=UTF-8 $1 | \
sed 's/\\r\\n/@PLACEHOLDER@/g' | \
sed 's/\\n/ /g' | \
sed 's/@PLACEHOLDER@/\\n/g' > $2
}
I'm not used to writing shell functions.
There may be many edge cases and other considerations not handled here but this first pass works. To be specific with how this function is used in practice, it is sent to the --to-command=
argument of a call to tar
, such that the above process is performed for every file extracted from the tar archive. Use case is preprocessing tabular data for upload to a database.
I'm not sure if we can do the operation in place or not.
Open to using tools other than sed
, e.g. tr
, awk
or perl
(though I don't think the latter is necessary).
(Highly simplified) example input:
apple|orange|\n|lemon\r\nrasperry|strawberry|mango|\n\r\n
Example output:
apple|orange| |lemon\nrasperry|strawberry|mango| \n