Hapus carriage return di Unix


Jawaban:


261

Aku akan menganggap Anda berarti tombol kembali ( CR, "\r", 0x0d) di ujung garis bukan hanya membabi buta dalam file (Anda mungkin memiliki mereka di tengah-tengah string untuk semua aku tahu). Menggunakan file uji ini dengan hanya CRpada akhir baris pertama:

$ 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 adalah cara untuk pergi jika diinstal pada sistem Anda:

$ cat infile | dos2unix -U | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Jika karena alasan tertentu dos2unixtidak tersedia untuk Anda, maka sedakan melakukannya:

$ cat infile | sed 's/\r$//' | od -c
0000000   h   e   l   l   o  \n   g   o   o   d   b   y   e  \n
0000016

Jika karena alasan tertentu sedtidak tersedia untuk Anda, maka edakan melakukannya dengan cara yang rumit:

$ 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

Jika Anda tidak memiliki salah satu alat yang diinstal pada kotak Anda, Anda punya masalah lebih besar daripada mencoba mengonversi file :-)


13
\rhanya bekerja dengan sed GNU, kalau tidak Anda bisa melakukan ini:sed `echo "s/\r//"`
lapo

15
Tidak sedjuga echomengenali \rdi MacO. Dalam hal ini printf "\r"tampaknya hanya berfungsi.
Steve Powell

30
Untuk menguraikan komentar @ steve: Di Mac, gunakan yang berikut ini: sed "s/$(printf '\r')\$//"
mklement0

7
Untuk memperbaiki masalah pada mac, Anda juga dapat awalan string sed-kutip tunggal dengan $seperti ini: sed $'s@\r@@g' |od -c (tetapi jika Anda akan menggantinya dengan \nAnda perlu menghindarinya)
nhed

1
Saya tidak 100% yakin, tetapi untuk OS X, menggunakan CTRL-V + CTRL-Mdi tempat \rsepertinya akan bekerja.

240
tr -d '\r' < infile > outfile

Lihat tr (1)


4
Tidak hebat: 1. tidak bekerja di tempat, 2. dapat menggantikan juga tidak di EOL (yang mungkin atau mungkin tidak seperti yang Anda inginkan ...).
Tomasz Gandor

10
1. Sebagian besar alat unixy bekerja seperti itu, dan biasanya cara paling aman untuk melakukan hal-hal karena jika Anda mengacaukan Anda masih memiliki yang asli. 2. Pertanyaan sebagaimana dinyatakan adalah untuk menghapus carriage return, bukan untuk mengkonversi akhir baris. Tetapi ada banyak jawaban lain yang mungkin bisa membantu Anda dengan lebih baik.
Henrik Gustafsson

1
Jika Anda trtidak mendukung \rpelarian, coba '\015'atau mungkin secara literal '^M'(dalam banyak shell pada banyak terminal, ctrl-V ctrl-M akan menghasilkan karakter ctrl-M literal).
tripleee

Jadi bagaimana seseorang mengubahnya ketika Anda inginkan outfile = infile?
Christopher

3
@donlan, akhir respon tetapi Anda biasanya menggunakan sesuatu seperti: someProg <in >out && mv out in.
paxdiablo

38

Sekolah tua:

tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns

32

Cara paling sederhana di Linux, menurut saya,

sed -i 's/\r$//g' <filename>

The kutipan yang kuat di sekitar operator substitusi 's/\r//'yang penting . Tanpa mereka shell akan menafsirkan \rsebagai pelarian + r dan menguranginya menjadi dataran r, dan menghapus semua huruf kecil r. Itu sebabnya jawaban yang diberikan di atas pada tahun 2009 oleh Rob tidak berhasil.

Dan menambahkan /gpengubah memastikan bahwa banyak \rpun akan dihapus, dan tidak hanya yang pertama.



7

sed -i s/\r// <filename>atau semacamnya; lihat man sedatau kekayaan informasi yang tersedia di web mengenai penggunaan sed.

Satu hal yang perlu diperhatikan adalah makna yang tepat dari "carriage return" di atas; jika Anda benar-benar bermaksud karakter kontrol tunggal "carriage return", maka pola di atas benar. Jika Anda maksudkan, secara lebih umum, CRLF (carriage return dan feed line, yang merupakan bagaimana feed line diimplementasikan di Windows), maka Anda mungkin ingin mengganti \r\nsaja. Umpan baris baru (baris baru) di Linux / Unix adalah \n.


Saya mencoba menggunakan -> sed 's / \ r \ n / = /' countryNew.txt> demo.txt yang tidak berfungsi. "Harimau" "Singa."
Suvasis

kita harus mengambil itu berarti Anda berada di mac? Saya perhatikan bahwa sed sed tampaknya memiliki perintah dan set fitur yang berbeda secara default daripada kebanyakan versi Linux ...
jsh

4
FYI, s/\r//sepertinya tidak menghapus carriage return di OS X, tampaknya menghapus rkarakter literal sebagai gantinya. Saya belum yakin mengapa itu belum. Mungkin itu ada hubungannya dengan cara string dikutip? Sebagai solusinya, menggunakan CTRL-V + CTRL-Mdi tempat \rtampaknya berfungsi.

6

Jika Anda adalah pengguna Vi, Anda dapat membuka file dan menghapus carriage return dengan:

:%s/\r//g

atau dengan

:1,$ s/^M//

Perhatikan bahwa Anda harus mengetikkan ^ M dengan menekan ctrl-v dan kemudian ctrl-m.


2
Tidak hebat: jika file memiliki CR pada setiap baris (yaitu file DOS yang benar), vim akan memuatnya dengan filetype = dos, dan tidak menunjukkan ^M-s sama sekali. Berkeliling ini adalah satu ton penekanan tombol, yang bukan untuk apa vim dibuat;). Saya hanya akan pergi sed -i, dan kemudian `-e 's / \ r // //' untuk membatasi penghapusan untuk CRs di EOL.
Tomasz Gandor

6

Sekali lagi solusi ... Karena selalu ada satu lagi:

perl -i -pe 's/\r//' filename

Ini bagus karena sudah ada dan berfungsi dalam setiap rasa unix / linux yang pernah saya gunakan.


3

Orang lain merekomendasikan dos2unixdan saya sangat merekomendasikannya juga. Saya hanya memberikan lebih banyak detail.

Jika terpasang, lompat ke langkah berikutnya. Jika belum diinstal, saya akan merekomendasikan menginstalnya melalui yumseperti:

yum install dos2unix

Maka Anda bisa menggunakannya seperti:

dos2unix fileIWantToRemoveWindowsReturnsFrom.txt

2

Jika Anda menggunakan OS (seperti OS X) yang tidak memiliki dos2unixperintah tetapi memang memiliki juru bahasa Python (versi 2.5+), perintah ini setara dengan dos2unixperintah:

python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"

Ini menangani kedua file bernama pada baris perintah serta pipa dan pengalihan, sama seperti dos2unix. Jika Anda menambahkan baris ini ke file ~ / .bashrc Anda (atau file profil yang setara untuk shell lain):

alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""

... saat berikutnya Anda masuk (atau menjalankan source ~/.bashrcsesi saat ini), Anda akan dapat menggunakan dos2unixnama pada baris perintah dengan cara yang sama seperti pada contoh lainnya.


2

Ini masalahnya,

%0dadalah karakter carriage return. Untuk membuatnya kompatibel dengan Unix. Kita perlu menggunakan perintah di bawah ini.

dos2unix fileName.extension fileName.extension


1

coba ini untuk mengubah file dos menjadi file unix:

file fromdos


1

Untuk UNIX ... Saya perhatikan dos2unix menghapus header Unicode dari file UTF-8 saya. Di bawah git bash (Windows), skrip berikut tampaknya berfungsi dengan baik. Ini menggunakan sed. Perhatikan itu hanya menghilangkan carriage-return di ujung garis, dan mempertahankan header Unicode.

#!/bin/bash

inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"

1

Jika Anda menjalankan lingkungan X dan memiliki editor yang tepat (kode studio visual), maka saya akan mengikuti rekomendasi ini:

Visual Studio Code: Cara menampilkan akhir baris

Pergi saja ke sudut kanan bawah layar Anda, kode studio visual akan menunjukkan kepada Anda baik pengkodean file dan konvensi akhir baris diikuti oleh file, hanya dengan klik sederhana Anda dapat beralih di sekitar.

Cukup gunakan kode visual sebagai pengganti notepad ++ di lingkungan linux dan Anda sudah siap.


Atau gunakan Notepad++perintah untuk Edit / EOL Conversion / Unix (LF)di sistem Windows Anda sebelum menyalin file ke sistem Linux Anda.
Jesse Chisholm

1

Menghapus \rpada sistem UNIX® apa pun:

Sebagian besar solusi yang ada dalam pertanyaan ini adalah khusus untuk GNU, dan tidak akan berfungsi pada OS X atau BSD; solusi di bawah ini akan bekerja pada lebih banyak sistem UNIX, dan dalam setiap shell, dari tcshhingga sh, masih bekerja bahkan di GNU / Linux juga.

Diuji pada OS X, OpenBSD dan NetBSD di tcsh, dan pada Debian GNU / Linux di bash.


Dengan sed:

Di tcshdalam OS X, sedcuplikan berikut ini dapat digunakan bersama-sama dengan printf, karena tidak ada sedatau echomenangani \rdengan cara khusus seperti yang dilakukan GNU:

sed `printf 's/\r$//g'` input > output

Dengan tr:

Pilihan lain adalah tr:

tr -d '\r' < input > output

Perbedaan antara seddan tr:

Akan muncul bahwa trmempertahankan kurangnya baris tambahan dari file input, sedangkan sedpada OS X dan NetBSD (tetapi tidak pada OpenBSD atau GNU / Linux) menyisipkan baris tambahan di akhir file bahkan jika input tidak ada tertinggal \ratau \ndi akhir file.


Pengujian:

Berikut ini beberapa contoh pengujian yang dapat digunakan untuk memastikan ini berfungsi pada sistem Anda, menggunakan printfdan hexdump -C; atau od -cdapat juga digunakan jika sistem Anda tidak ada 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
% 

0

Saya telah menggunakan python untuk itu, ini kode saya;

end1='/home/.../file1.txt'
end2='/home/.../file2.txt'
with open(end1, "rb") as inf:
     with open(end2, "w") as fixed:
        for line in inf:
            line = line.replace("\n", "")
            line = line.replace("\r", "")
            fixed.write(line)

0

Meskipun itu adalah posting yang lebih tua, baru-baru ini saya menemukan masalah yang sama. Karena saya memiliki semua file untuk diganti nama di dalam / tmp / blah_dir / karena setiap file dalam direktori ini memiliki "/ r" karakter trailing (menunjukkan "?" Di akhir file), jadi melakukannya dengan cara skrip hanya bisa saya pikirkan.

Saya ingin menyimpan file terakhir dengan nama yang sama (tanpa karakter apa pun). Dengan sed, masalahnya adalah nama file keluaran yang saya perlu menyebutkan sesuatu yang lain (yang saya tidak mau).

Saya mencoba opsi lain seperti yang disarankan di sini (tidak dianggap dos2unix karena beberapa keterbatasan) tetapi tidak berhasil.

Saya mencoba dengan "awk" akhirnya yang bekerja di mana saya menggunakan "\" sebagai pembatas dan mengambil bagian pertama :

triknya adalah:

echo ${filename}|awk -F"\r" '{print $1}'

Di bawah cuplikan skrip yang saya gunakan (di mana saya memiliki semua file memiliki "\ r" sebagai karakter tambahan di path / tmp / blah_dir /) untuk memperbaiki masalah saya:

cd /tmp/blah_dir/
for i in `ls`
  do
    mv   $i     $(echo $i | awk -F"\r" '{print $1}')
done

Catatan: Contoh ini tidak terlalu tepat meskipun dekat dengan apa yang saya kerjakan (Sebutkan di sini hanya untuk memberikan ide yang lebih baik tentang apa yang saya lakukan)


0

Saya membuat skrip shell ini untuk menghapus karakter. Ia bekerja dalam solaris dan topi merah:

#!/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

-1

Anda cukup melakukan ini:

$ echo $(cat input) > output

Tidak tahu mengapa seseorang memberi '-1'. Ini adalah jawaban yang sangat bagus (dan satu-satunya yang bekerja untuk saya).
FractalSpace

1
Oh, maaf, itu aku. Tunggu, lihat, itu benar-benar tidak bekerja untuk 'r'!
Viacheslav Rodionov

1
@FractalSpace Ini adalah ide yang buruk! Itu benar-benar menghancurkan semua spasi dalam file dan meninggalkan semua isi file yang akan ditafsirkan oleh shell. Cobalah dengan file yang berisi satu baris a * b...
Tom Fenech
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.