vi
DOS / Windows satırlarını programlı olarak Unix'e nasıl dönüştürebilirim (örneğin, kullanmıyorum )?
dos2unix
Ve unix2dos
komutlar belirli sistemlerde kullanılamaz. Bunları sed
/ awk
/ gibi komutlarla nasıl taklit edebilirim tr
?
vi
DOS / Windows satırlarını programlı olarak Unix'e nasıl dönüştürebilirim (örneğin, kullanmıyorum )?
dos2unix
Ve unix2dos
komutlar belirli sistemlerde kullanılamaz. Bunları sed
/ awk
/ gibi komutlarla nasıl taklit edebilirim tr
?
Yanıtlar:
tr
DOS'tan Unix'e dönüştürmek için kullanabilirsiniz ; ancak, bunu CR dosyanızda yalnızca bir CRLF bayt çiftinin ilk baytı olarak görünüyorsa yapabilirsiniz. Bu genellikle böyledir. Daha sonra şunları kullanırsınız:
tr -d '\015' <DOS-file >UNIX-file
Adın DOS-file
addan farklı olduğunu unutmayın UNIX-file
; aynı adı iki kez kullanmaya çalışırsanız, dosyada veri olmaz.
Bunu başka türlü yapamazsınız (standart 'tr' ile).
Bir komut dosyasına satır başı nasıl girileceğini biliyorsanız ( control-V,control-M control-M girmek için), o zaman:
sed 's/^M$//' # DOS to Unix
sed 's/$/^M/' # Unix to DOS
burada '^ M' kontrol-M karakteridir. bash
ANSI-C Alıntılama mekanizmasını, satır başını belirtmek için de kullanabilirsiniz :
sed $'s/\r$//' # DOS to Unix
sed $'s/$/\r/' # Unix to DOS
Bununla birlikte, bunu çok sık yapmak zorunda kalacaksanız (bir kereden fazla, kabaca konuşursak), dönüşüm programlarını yüklemek çok daha mantıklıdır (ör. dos2unix
Ve unix2dos
, veya belki dtou
veutod
) ve kullanmak .
Tüm dizinleri ve alt dizinleri işlemeniz gerekiyorsa, şunları kullanabilirsiniz zip
:
zip -r -ll zipfile.zip somedir/
unzip zipfile.zip
Bu satır sonları CRLF'den CR'ye değiştirilmiş bir zip arşivi oluşturur. unzip
daha sonra dönüştürülen dosyaları tekrar yerine koyacaktır (ve dosyaya göre dosya soracaksınız - yanıtlayabilirsiniz: Herkese evet). Bunu işaret ettiği için @vmsnomad'a verilen krediler.
tr -d '\015' <DOS-file >UNIX-file
where DOS-file
== kullanmak UNIX-file
yalnızca boş bir dosya ile sonuçlanır. Çıktı dosyası maalesef farklı bir dosya olmalıdır.
sed
seçeneği -i
(yerinde) çalışır; limitler bağlantılı dosyalar ve sembolik linklerdir. sort
Komut 'daima' vardır (1979 yılından bu yana, erken değil ise) desteklenen -o
girdi dosyalardan birini listeleyebilirsiniz seçeneği. Ancak bu kısmen sort
, çıktılarından herhangi birini yazmadan önce tüm girdilerini okumalıdır. Diğer programlar ara sıra girdi dosyalarından birinin üzerine yazmayı destekler. Kernighan & Pike'ın 'UNIX Programlama Ortamı' bölümünde problemlerden kaçınmak için genel amaçlı bir program (script) bulabilirsiniz .
sed -i $'s/\r$//' filename
Yerinde düzenlemek için -i seçeneğini kullandım: -. İnternet erişimi olmayan bir makine üzerinde çalışıyorum, bu yüzden yazılım kurulumu bir sorun.
tr -d "\r" < file
bir göz atın burada kullanarak örnekler için sed
:
# IN UNIX ENVIRONMENT: convert DOS newlines (CR/LF) to Unix format.
sed 's/.$//' # assumes that all lines end with CR/LF
sed 's/^M$//' # in bash/tcsh, press Ctrl-V then Ctrl-M
sed 's/\x0D$//' # works on ssed, gsed 3.02.80 or higher
# IN UNIX ENVIRONMENT: convert Unix newlines (LF) to DOS format.
sed "s/$/`echo -e \\\r`/" # command line under ksh
sed 's/$'"/`echo \\\r`/" # command line under bash
sed "s/$/`echo \\\r`/" # command line under zsh
sed 's/$/\r/' # gsed 3.02.80 or higher
sed -i
Yerinde dönüşüm için kullanın örn sed -i 's/..../' file
.
\r
:tr "\r" "\n" < infile > outfile
-d
daha sık özellikli ve "sadece yardımcı olmayacaktır \r
" durum.
\r
için \n
haritalama çift aralık dosyaların etkisi vardır; DOS ile biten her bir CRLF satırı \n\n
Unix'te olur .
POSIX ile bunu yapmak zor:
POSIX Sed desteklemiyor \r
veya \15
. Olsa bile, yerinde seçeneği -i
POSIX değildir
POSIX Awk destekliyor \r
ve \15
bu -i inplace
seçenek POSIX değil
d2u ve dos2unix değildir POSIX yardımcı programları , ancak eski olduğu
POSIX ex desteklemez \r
, \15
, \n
veya\12
Satır başlarını kaldırmak için:
ex -bsc '%!awk "{sub(/\r/,\"\")}1"' -cx file
Satır başı eklemek için:
ex -bsc '%!awk "{sub(/$/,\"\r\")}1"' -cx file
tr
desteklerine\r
benziyor . Böylece kullanabilirsiniz printf '%s\n' '%!tr -d "\r"' x | ex file
(kabul edilmiş olsa da, \r
hemen öncesinde olmasa bile kaldırıldı \n
). Ayrıca, POSIX tarafından -b
seçeneği ex
belirtilmedi.
Vim'yi -c {command} seçeneğiyle programlı olarak kullanabilirsiniz:
Dos Unix için:
vim file.txt -c "set ff=unix" -c ":wq"
Unix to dos:
vim file.txt -c "set ff=dos" -c ":wq"
"set ff = unix / dos", dosyanın dosya biçimini (ff) Unix / DOS satır sonu biçimine değiştir anlamına gelir
": wq", diske dosya yazmak ve düzenleyiciden çıkmak (komutu bir döngüde kullanmaya izin vermek) anlamına gelir
vi
ne :wq
anlama geldiğini bilir . 3 karakteri olmayanlar için 1) açık vi komut alanı, 2) yazma ve 3) çıkış.
Bir dosyayı yerinde dönüştürmek için
dos2unix <filename>
Dönüştürülen metni farklı bir dosyaya çıkarmak için
dos2unix -n <input-file> <output-file>
Ubuntu veya Debian'a şu şekilde yükleyebilirsiniz:
sudo apt install dos2unix
veya homebrew kullanarak macOS'ta
brew install dos2unix
Bu sorun standart araçlarla çözülebilir, ancak flip
20 yıl önce yazarı Rahul Dhesi tarafından yazılan komutu yüklemenizi tavsiye ettiğim için yeterince fazla tuzak var zoo
. Örneğin, ikili dosyaların yanlışlıkla tahrip edilmesinden kaçınırken, dosya formatlarını dönüştüren mükemmel bir iş çıkarır;
Şimdiye kadar yayınlanan çözümler, sorunun sadece bir kısmı ile ilgileniyor ve DOS / Windows CRLF'yi Unix'in LF'sine dönüştürüyor; eksik oldukları kısım DOS'un satır ayırıcısı olarak CRLF kullanması , Unix ise bir satır sonlandırıcısı olarak LF kullanmasıdır . Fark, bir DOS dosyasının (genellikle) dosyadaki son satırdan sonra hiçbir şeye sahip olmaması, Unix'in ise olmasıdır. Dönüştürmeyi düzgün bir şekilde yapmak için, son LF'yi eklemeniz gerekir (dosya sıfır uzunlukta değilse, yani içinde hiç satır yoksa). Bunun için en sevdiğim büyüm (Mac stili CR ile ayrılmış dosyaları işlemek için biraz eklenmiş mantıkla ve zaten unix biçiminde olan taciz dosyalarını değil) biraz perl:
perl -pe 'if ( s/\r\n?/\n/g ) { $f=1 }; if ( $f || ! $m ) { s/([^\n])\z/$1\n/ }; $m=1' PCfile.txt
Bunun, dosyanın Unixified sürümünü stdout'a gönderdiğini unutmayın. Dosyayı Unixified sürümüyle değiştirmek istiyorsanız perl'in -i
bayrağını ekleyin .
Dos2unix'e erişiminiz yoksa ancak bu sayfayı okuyabiliyorsanız, dos2unix.py'yi buradan kopyalayabilir / yapıştırabilirsiniz .
#!/usr/bin/env python
"""\
convert dos linefeeds (crlf) to unix (lf)
usage: dos2unix.py <input> <output>
"""
import sys
if len(sys.argv[1:]) != 2:
sys.exit(__doc__)
content = ''
outsize = 0
with open(sys.argv[1], 'rb') as infile:
content = infile.read()
with open(sys.argv[2], 'wb') as output:
for line in content.splitlines():
outsize += len(line) + 1
output.write(line + '\n')
print("Done. Saved %s bytes." % (len(content)-outsize))
Süper kullanıcıdan çapraz gönderi .
dos2unix
, varsayılan olarak tüm girdi dosyalarını dönüştürür . Kullanımınız -n
parametre anlamına gelir . Ve gerçek dos2unix
stdin'den okunan, dosyalar verilmezse stdout'a yazan bir filtredir.
PCRE ile süper duper kolay;
Komut dosyası olarak veya $@
dosyalarınızla değiştirin .
#!/usr/bin/env bash
perl -pi -e 's/\r\n/\n/g' -- $@
Bu, dosyalarınızın üzerine yazacaktır!
Bunu yalnızca bir yedeklemeyle (sürüm kontrolü veya başka bir şekilde) yapmanızı öneririm
--
. Bu çözümü seçtim, çünkü benim için anlaşılması ve uyarlanması kolay. FYI, anahtarların yaptığı şey budur: -p
"while input" döngüsünü varsayalım, -i
girdi dosyasını yerinde düzenleyin, -e
aşağıdaki komutu yürütün
Programsız daha basit bir awk çözümü:
awk -v ORS='\r\n' '1' unix.txt > dos.txt
Teknik olarak '1' sizin programınızdır, b / c awk seçeneği verildiğinde bir tane gerektirir.
GÜNCELLEME : Bu sayfayı uzun süre ilk kez tekrar ziyaret ettikten sonra, henüz hiç kimsenin dahili bir çözüm yayınlamadığını fark ettim, işte burada:
while IFS= read -r line;
do printf '%s\n' "${line%$'\r'}";
done < dos.txt > unix.txt
awk -v RS='\r\n' '1' dos.txt > unix.txt
awk
veya sed
çözeltiden çok daha yavaştır . Ayrıca, while IFS= read -r line
giriş satırlarını sadakatle korumak için kullanmalısınız , aksi takdirde öndeki ve sondaki boşluk kesilir (alternatif olarak read
komutta değişken adı kullanmayın ve onunla çalışın $REPLY
).
Sadece aynı soruyu düşünmek zorunda kaldım (Windows tarafında, ancak linux için eşit derecede uygulanabilir.) Şaşırtıcı kimse, eski eski zip -ll
seçeneği (Info-ZIP) kullanarak metin dosyaları için CRLF <-> LF dönüşümü yapmanın çok otomatik bir yolundan bahsetmedi :
zip -ll textfiles-lf.zip files-with-crlf-eol.*
unzip textfiles-lf.zip
NOT: Bu, orijinal dosya adlarını koruyan ancak satır sonlarını LF'ye dönüştüren bir zip dosyası oluşturur. Sonraunzip
dosyaları zip'ed olarak, yani orijinal isimleriyle (ancak LF uçlarıyla) ayıklayın, böylece varsa yerel orijinal dosyaların üzerine yazılmasını isteyin.
İlgili alıntı zip --help
:
zip --help
...
-l convert LF to CR LF (-ll CR LF to LF)
ilginç Windows benim git-bash sed ""
hile zaten yaptı:
$ echo -e "abc\r" >tst.txt
$ file tst.txt
tst.txt: ASCII text, with CRLF line terminators
$ sed -i "" tst.txt
$ file tst.txt
tst.txt: ASCII text
Benim tahminim sed giriş satırları okurken onları görmezden gelir ve her zaman çıkış üzerine unix satır sonları yazar.
Mac osx için homebrew yüklüyse [ http://brew.sh/ürlü[1]
brew install dos2unix
for csv in *.csv; do dos2unix -c mac ${csv}; done;
Bu komut, dosyaları yerinde değiştireceğinden dosyaların kopyalarını oluşturduğunuzdan emin olun. -C mac seçeneği, anahtarın osx ile uyumlu olmasını sağlar.
-c mac
, OS X öncesi CR
sadece yeni satırları dönüştürmek için kullanmamalıdır . Bu modu yalnızca Mac OS 9'a veya daha öncesine ait dosyalar için kullanmak istersiniz.
Awk kullanabilirsiniz. Kayıt ayırıcıyı ( RS
) olası tüm yeni satır karakteri veya karakterlerle eşleşen bir normal ifade olarak ayarlayın . Ve çıkış kayıt ayırıcısını ( ORS
) unix tarzı yeni satır karakterine ayarlayın.
awk 'BEGIN{RS="\r|\n|\r\n|\n\r";ORS="\n"}{print}' windows_or_macos.txt > unix.txt
git diff
^ M, vim'de düzenlendi)
Linux'ta sed ile ^ M (ctrl-M) 'nix satırlarına (^ J) dönüştürmek kolaydır.
CLI'de böyle bir şey olacak, aslında metinde bir satır sonu olacak. Ancak, \ bu ^ J'yi sed'e iletir:
sed 's/^M/\
/g' < ffmpeg.log > new.log
Bunu, yazarken ^ V (ctrl-V), ^ M (ctrl-M) ve \ (ters eğik çizgi) kullanarak elde edersiniz:
sed 's/^V^M/\^V^J/g' < ffmpeg.log > new.log
sed --expression='s/\r\n/\n/g'
Soru sed'den bahsettiği için, bunu başarmak için sed kullanmanın en basit yolu budur. İfadenin söylediği, tüm satır başı ve satır beslemenin yalnızca satır beslemeyle değiştirilmesidir. Windows'dan Unix'e geçtiğinizde ihtiyacınız olan şey budur. Çalıştığını doğruladım.
Jonathan Leffler'ın Unix to DOS çözümünün bir uzantısı olarak, dosyanın geçerli satır sonlarından emin değilseniz güvenli bir şekilde DOS'a dönüştürmek için:
sed '/^M$/! s/$/^M/'
Bu, satırın CRLF'ye dönüştürülmeden önce CRLF'de bitmediğini kontrol eder.
Kabul edilen cevaba dayalı bir komut dosyası hazırladım, böylece sonunda ek bir dosyaya ihtiyaç duymadan ve daha sonra kaldırıp yeniden adlandırmadan doğrudan dönüştürebilirsiniz.
convert-crlf-to-lf() {
file="$1"
tr -d '\015' <"$file" >"$file"2
rm -rf "$file"
mv "$file"2 "$file"
}
"file1.txt2" gibi bir dosyanız varsa, "file1.txt2" nin zaten mevcut olmadığından veya üzerine yazılacağından emin olun, bunu dosyayı depolamak için geçici bir yer olarak kullanıyorum.
Ben sed 's / ^ M $ //' file.txt OSX ve diğer bazı yöntemleri denedim ( http://www.thingy-ma-jig.co.uk/blog/25-11-2010/fixing- dos-line-endings veya http://hintsforums.macworld.com/archive/index.php/t-125.html ). Hiçbiri işe yaramadı, dosya değişmeden kaldı (btw Ctrl-v Enter, ^ M'yi yeniden üretmek için gerekliydi). Sonunda TextWrangler kullandım. Kesinlikle komut satırı değil ama işe yarıyor ve şikayet etmiyor.
dos2unix
paket yöneticinizi kullanarak yükleyin , gerçekten çok daha basittir ve çoğu platformda mevcuttur.