Apa cara paling sederhana untuk menghapus semua pengembalian carriage \r
dari file di Unix?
Apa cara paling sederhana untuk menghapus semua pengembalian carriage \r
dari file di Unix?
Jawaban:
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 dos2unix
tidak tersedia untuk Anda, maka sed
akan 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 sed
tidak tersedia untuk Anda, maka ed
akan 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 :-)
\r
hanya bekerja dengan sed GNU, kalau tidak Anda bisa melakukan ini:sed `echo "s/\r//"`
sed
juga echo
mengenali \r
di MacO. Dalam hal ini printf "\r"
tampaknya hanya berfungsi.
sed "s/$(printf '\r')\$//"
$
seperti ini: sed $'s@\r@@g' |od -c
(tetapi jika Anda akan menggantinya dengan \n
Anda perlu menghindarinya)
tr -d '\r' < infile > outfile
Lihat tr (1)
tr
tidak mendukung \r
pelarian, coba '\015'
atau mungkin secara literal '^M'
(dalam banyak shell pada banyak terminal, ctrl-V ctrl-M akan menghasilkan karakter ctrl-M literal).
outfile = infile
?
someProg <in >out && mv out in
.
Sekolah tua:
tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
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 \r
sebagai 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 /g
pengubah memastikan bahwa banyak \r
pun akan dihapus, dan tidak hanya yang pertama.
sed -i s/\r// <filename>
atau semacamnya; lihat man sed
atau 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\n
saja. Umpan baris baru (baris baru) di Linux / Unix adalah \n
.
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.
^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.
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.
Orang lain merekomendasikan dos2unix
dan saya sangat merekomendasikannya juga. Saya hanya memberikan lebih banyak detail.
Jika terpasang, lompat ke langkah berikutnya. Jika belum diinstal, saya akan merekomendasikan menginstalnya melalui yum
seperti:
yum install dos2unix
Maka Anda bisa menggunakannya seperti:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
Jika Anda menggunakan OS (seperti OS X) yang tidak memiliki dos2unix
perintah tetapi memang memiliki juru bahasa Python (versi 2.5+), perintah ini setara dengan dos2unix
perintah:
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 ~/.bashrc
sesi saat ini), Anda akan dapat menggunakan dos2unix
nama pada baris perintah dengan cara yang sama seperti pada contoh lainnya.
Ini masalahnya,
%0d
adalah karakter carriage return. Untuk membuatnya kompatibel dengan Unix. Kita perlu menggunakan perintah di bawah ini.
dos2unix fileName.extension fileName.extension
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"
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.
Notepad++
perintah untuk Edit / EOL Conversion / Unix (LF)
di sistem Windows Anda sebelum menyalin file ke sistem Linux Anda.
\r
pada 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 tcsh
hingga sh
, masih bekerja bahkan di GNU / Linux juga.
Diuji pada OS X, OpenBSD dan NetBSD di tcsh
, dan pada Debian GNU / Linux di bash
.
sed
:Di tcsh
dalam OS X, sed
cuplikan berikut ini dapat digunakan bersama-sama dengan printf
, karena tidak ada sed
atau echo
menangani \r
dengan cara khusus seperti yang dilakukan GNU:
sed `printf 's/\r$//g'` input > output
tr
:Pilihan lain adalah tr
:
tr -d '\r' < input > output
sed
dan tr
:Akan muncul bahwa tr
mempertahankan kurangnya baris tambahan dari file input, sedangkan sed
pada OS X dan NetBSD (tetapi tidak pada OpenBSD atau GNU / Linux) menyisipkan baris tambahan di akhir file bahkan jika input tidak ada tertinggal \r
atau \n
di akhir file.
Berikut ini beberapa contoh pengujian yang dapat digunakan untuk memastikan ini berfungsi pada sistem Anda, menggunakan printf
dan hexdump -C
; atau od -c
dapat 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
%
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)
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
Anda cukup melakukan ini:
$ echo $(cat input) > output
a * b
...