Cách đơn giản nhất để loại bỏ tất cả các trả về vận chuyển \r
từ một tệp trong Unix là gì?
Cách đơn giản nhất để loại bỏ tất cả các trả về vận chuyển \r
từ một tệp trong Unix là gì?
Câu trả lời:
Tôi sẽ giả sử bạn tự xuống dòng trung bình ( CR, "\r"
, 0x0d
) tại đầu dòng chứ không phải chỉ một cách mù quáng trong một tập tin (bạn có thể có họ ở giữa chuỗi cho tất cả tôi biết). Chỉ sử dụng tệp thử nghiệm này CRở cuối dòng đầu tiên:
$ cat infile
hello
goodbye
$ cat infile | od -c
0000000 h e l l o \r \n g o o d b y e \n
0000017
dos2unix
là cách để đi nếu nó được cài đặt trên hệ thống của bạn:
$ cat infile | dos2unix -U | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
Nếu vì lý do nào đó dos2unix
không có sẵn cho bạn, thì sed
sẽ làm điều đó:
$ cat infile | sed 's/\r$//' | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
Nếu vì lý do nào đó sed
không có sẵn cho bạn, thì ed
sẽ làm điều đó, theo một cách phức tạp:
$ echo ',s/\r\n/\n/
> w !cat
> Q' | ed infile 2>/dev/null | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
Nếu bạn không cài đặt bất kỳ công cụ nào trong hộp của mình, bạn sẽ gặp vấn đề lớn hơn là cố gắng chuyển đổi tệp :-)
\r
chỉ hoạt động với GNU sed, bạn có thể làm điều này:sed `echo "s/\r//"`
sed
phải cũng không echo
nhận ra \r
trên MacOs. Trong trường hợp này chỉ printf "\r"
xuất hiện để làm việc.
sed "s/$(printf '\r')\$//"
$
như vậy: sed $'s@\r@@g' |od -c
(nhưng nếu bạn thay thế bằng thì \n
bạn sẽ cần phải thoát nó)
tr -d '\r' < infile > outfile
Xem tr (1)
tr
không hỗ trợ \r
thoát, hãy thử '\015'
hoặc có thể bằng chữ '^M'
(trong nhiều shell trên nhiều thiết bị đầu cuối, ctrl-V ctrl-M sẽ tạo ra một ký tự ctrl-M bằng chữ).
outfile = infile
?
someProg <in >out && mv out in
.
Cách đơn giản nhất trên Linux là, theo ý kiến khiêm tốn của tôi,
sed -i 's/\r$//g' <filename>
Các trích dẫn mạnh mẽ xung quanh toán tử thay thế 's/\r//'
là rất cần thiết . Không có chúng, shell sẽ diễn giải \r
như một lối thoát + r và giảm nó xuống một đồng bằng r
, và loại bỏ tất cả chữ thường r
. Đó là lý do tại sao câu trả lời được đưa ra ở trên vào năm 2009 bởi Rob không hoạt động.
Và việc thêm công cụ /g
sửa đổi đảm bảo rằng thậm chí nhiều cái \r
sẽ bị loại bỏ, và không chỉ cái đầu tiên.
sed -i s/\r// <filename>
hoặc somesuch; xem man sed
hoặc sự giàu có của thông tin có sẵn trên web liên quan đến việc sử dụng sed
.
Một điều cần chỉ ra là ý nghĩa chính xác của "vận chuyển trở lại" ở trên; nếu bạn thực sự có nghĩa là ký tự điều khiển duy nhất "trở về vận chuyển", thì mẫu ở trên là chính xác. Nếu bạn có nghĩa là, nói chung, CRLF (trả về vận chuyển và nguồn cấp dữ liệu, đó là cách thức cung cấp dòng được thực hiện trong Windows), thì có lẽ bạn muốn thay thế \r\n
. Nguồn cấp dữ liệu trần (dòng mới) trong Linux / Unix là \n
.
Nếu bạn là người dùng Vi, bạn có thể mở tệp và xóa trả lại vận chuyển bằng:
:%s/\r//g
Hoặc với
:1,$ s/^M//
Lưu ý rằng bạn nên gõ ^ M bằng cách nhấn ctrl-v và sau đó ctrl-m.
^M
-s. Xung quanh đây là một tấn tổ hợp phím, đó không phải là thứ mà vim được tạo ra;). Tôi chỉ cần đi sed -i
, và sau đó `-e 's / \ r $ // g' để giới hạn loại bỏ đối với CR tại EOL.
Thêm một giải pháp nữa ... Bởi vì luôn có thêm một giải pháp nữa:
perl -i -pe 's/\r//' filename
Thật tuyệt vì nó đã được sử dụng và hoạt động trong mọi hương vị của unix / linux mà tôi đã làm việc cùng.
Một số người khác giới thiệu dos2unix
và tôi cũng khuyên bạn nên nó. Tôi chỉ cung cấp thêm chi tiết.
Nếu được cài đặt, nhảy sang bước tiếp theo. Nếu chưa được cài đặt, tôi khuyên bạn nên cài đặt nó qua yum
như:
yum install dos2unix
Sau đó, bạn có thể sử dụng nó như:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
Nếu bạn đang sử dụng HĐH (như OS X) không có dos2unix
lệnh nhưng có trình thông dịch Python (phiên bản 2.5+), lệnh này tương đương với dos2unix
lệnh:
python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"
Điều này xử lý cả các tệp được đặt tên trên dòng lệnh cũng như các đường ống và chuyển hướng, giống như dos2unix
. Nếu bạn thêm dòng này vào tệp ~ / .bashrc (hoặc tệp hồ sơ tương đương cho các shell khác):
alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""
... Lần sau khi bạn đăng nhập (hoặc chạy source ~/.bashrc
trong phiên hiện tại), bạn sẽ có thể sử dụng dos2unix
tên trên dòng lệnh theo cách tương tự như trong các ví dụ khác.
Đây là điều,
%0d
là nhân vật trở về xe ngựa. Để làm cho nó tương thích với Unix. Chúng ta cần sử dụng lệnh dưới đây.
dos2unix fileName.extension fileName.extension
Đối với UNIX ... Tôi đã nhận thấy dos2unix loại bỏ các tiêu đề Unicode tạo thành tệp UTF-8 của tôi. Theo git bash (Windows), đoạn script sau dường như hoạt động tốt. Nó sử dụng sed. Lưu ý rằng nó chỉ loại bỏ trả về vận chuyển ở cuối dòng và bảo toàn các tiêu đề Unicode.
#!/bin/bash
inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"
Nếu bạn đang chạy một môi trường X và có một trình soạn thảo thích hợp (mã studio trực quan), thì tôi sẽ làm theo lời giới thiệu:
Visual Studio Code: Cách hiển thị kết thúc dòng
Chỉ cần đi đến góc dưới bên phải của màn hình của bạn, mã studio hình ảnh sẽ hiển thị cho bạn cả mã hóa tệp và kết thúc dòng theo sau là tệp, chỉ với một cú nhấp chuột đơn giản, bạn có thể chuyển đổi xung quanh.
Chỉ cần sử dụng mã trực quan để thay thế cho notepad ++ trên môi trường linux và bạn đã sẵn sàng sử dụng.
Notepad++
lệnh Edit / EOL Conversion / Unix (LF)
của hệ thống Windows của bạn trước khi sao chép tệp vào hệ thống Linux của bạn.
\r
trên mọi hệ thống UNIX®:Hầu hết các giải pháp hiện có trong câu hỏi này là dành riêng cho GNU và sẽ không hoạt động trên OS X hoặc BSD; các giải pháp bên dưới sẽ hoạt động trên nhiều hệ thống UNIX khác, và trong mọi hệ vỏ, từ tcsh
đến sh
, nhưng vẫn hoạt động ngay cả trên GNU / Linux.
Đã thử nghiệm trên OS X, OpenBSD và NetBSD tcsh
và trên Debian GNU / Linux bash
.
sed
:Trong tcsh
trên OS X, sau sed
đoạn có thể được sử dụng cùng với printf
, như không phải sed
và cũng không echo
xử lý \r
theo cách đặc biệt như GNU làm:
sed `printf 's/\r$//g'` input > output
tr
:Một lựa chọn khác là tr
:
tr -d '\r' < input > output
sed
và tr
:Dường như tr
thiếu một dòng mới ở tệp đầu vào, trong khi sed
trên OS X và NetBSD (nhưng không phải trên OpenBSD hoặc GNU / Linux) sẽ chèn một dòng mới ở cuối tập tin ngay cả khi đầu vào bị thiếu dấu \r
hoặc \n
ở cuối tập tin
Đây là một số thử nghiệm mẫu có thể được sử dụng để đảm bảo điều này hoạt động trên hệ thống của bạn, sử dụng printf
và hexdump -C
; cách khác, od -c
cũng có thể được sử dụng nếu hệ thống của bạn bị thiếu hexdump
:
% printf 'a\r\nb\r\nc' | hexdump -C
00000000 61 0d 0a 62 0d 0a 63 |a..b..c|
00000007
% printf 'a\r\nb\r\nc' | ( sed `printf 's/\r$//g'` /dev/stdin > /dev/stdout ) | hexdump -C
00000000 61 0a 62 0a 63 0a |a.b.c.|
00000006
% printf 'a\r\nb\r\nc' | ( tr -d '\r' < /dev/stdin > /dev/stdout ) | hexdump -C
00000000 61 0a 62 0a 63 |a.b.c|
00000005
%
Mặc dù đó là một bài viết cũ hơn, gần đây tôi đã gặp vấn đề tương tự. Vì tôi có tất cả các tệp để đổi tên bên trong / tmp / blah_dir / vì mỗi tệp trong thư mục này có ký tự dấu "/ r" (hiển thị "?" Ở cuối tệp), nên tôi chỉ có thể nghĩ ra cách viết kịch bản.
Tôi muốn lưu tập tin cuối cùng có cùng tên (mà không theo dõi bất kỳ ký tự nào). Với sed, vấn đề là tên tệp đầu ra mà tôi cần phải đề cập đến một cái gì đó khác (mà tôi không muốn).
Tôi đã thử các tùy chọn khác như được đề xuất ở đây (không được coi là dos2unix vì một số hạn chế) nhưng không hiệu quả.
Cuối cùng tôi đã thử với "awk", cái mà tôi đã sử dụng "\ r" làm dấu phân cách và lấy phần đầu tiên :
mẹo là:
echo ${filename}|awk -F"\r" '{print $1}'
Đoạn mã bên dưới tôi đã sử dụng (trong đó tôi có tất cả các tệp có "\ r" là ký tự ở đường dẫn / tmp / blah_dir /) để khắc phục sự cố của tôi:
cd /tmp/blah_dir/
for i in `ls`
do
mv $i $(echo $i | awk -F"\r" '{print $1}')
done
Lưu ý: Ví dụ này không chính xác lắm mặc dù gần với những gì tôi đã làm (Đề cập ở đây chỉ để đưa ra ý tưởng tốt hơn về những gì tôi đã làm)
Tôi đã tạo shell-script này để xóa ký tự \ r. Nó hoạt động trong solaris và mũ đỏ:
#!/bin/ksh
LOCALPATH=/Any_PATH
for File in `ls ${LOCALPATH}`
do
ARCACT=${LOCALPATH}/${File}
od -bc ${ARCACT}|sed -n 'p;n'|sed 's/015/012/g'|awk '{$1=""; print $0}'|sed 's/ /\\/g'|awk '{printf $0;}'>${ARCACT}.TMP
printf "`cat ${ARCACT}.TMP`"|sed '/^$/d'>${ARCACT}
rm ${ARCACT}.TMP
done
exit 0
bạn chỉ có thể làm điều này:
$ echo $(cat input) > output
a * b
...