วิธีที่ง่ายที่สุดในการลบการรับคืนทั้งหมด\r
ออกจากไฟล์ใน Unix คืออะไร?
วิธีที่ง่ายที่สุดในการลบการรับคืนทั้งหมด\r
ออกจากไฟล์ใน Unix คืออะไร?
คำตอบ:
ฉันจะถือว่าคุณผลตอบแทนการขนส่งเฉลี่ย ( CR, "\r"
, 0x0d
) ที่ปลายของเส้นมากกว่าแค่สุ่มสี่สุ่มห้าภายในแฟ้ม (คุณอาจจะมีพวกเขาในช่วงกลางของสตริงสำหรับทุกฉันรู้) การใช้ไฟล์ทดสอบนี้โดยใช้CRที่ท้ายบรรทัดแรกเท่านั้น:
$ 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
เป็นวิธีที่จะไปหากติดตั้งในระบบของคุณ:
$ cat infile | dos2unix -U | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
หากเหตุผลบางอย่างdos2unix
ไม่สามารถใช้ได้สำหรับคุณแล้วsed
จะทำ:
$ cat infile | sed 's/\r$//' | od -c
0000000 h e l l o \n g o o d b y e \n
0000016
หากเหตุผลบางอย่างsed
ไม่สามารถใช้ได้กับคุณแล้วed
จะทำในวิธีที่ซับซ้อน:
$ 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
หากคุณไม่ได้มีการใด ๆของเครื่องมือเหล่านั้นติดตั้งอยู่ในกล่องของคุณคุณได้มีปัญหาใหญ่กว่าพยายามที่จะแปลงไฟล์ :-)
\r
ใช้งานได้กับ GNU เท่านั้นไม่เช่นนั้นคุณสามารถทำได้:sed `echo "s/\r//"`
sed
มิได้echo
รับรู้\r
ใน MacOs ในกรณีนี้printf "\r"
ใช้งานได้เท่านั้น
sed "s/$(printf '\r')\$//"
$
เช่นดังนั้น: sed $'s@\r@@g' |od -c
( แต่ถ้าคุณจะเข้ามาแทนที่ด้วย\n
คุณจะต้องหนีมัน)
tr -d '\r' < infile > outfile
ดูtr (1)
tr
ไม่สนับสนุนการ\r
หลบหนีลอง'\015'
หรืออาจเป็นตัวอักษร'^M'
(ในเชลล์จำนวนมากบนเทอร์มินัลจำนวนมาก ctrl-V ctrl-M จะสร้างตัวอักษร ctrl-M ตามตัวอักษร)
outfile = infile
?
someProg <in >out && mv out in
แต่คุณมักจะใช้สิ่งที่ชอบ:
โรงเรียนเก่า:
tr -d '\r' < filewithcarriagereturns > filewithoutcarriagereturns
วิธีที่ง่ายที่สุดบน Linux คือในความเห็นของฉัน
sed -i 's/\r$//g' <filename>
คำพูดที่แข็งแกร่งทั่วประกอบการทดแทน's/\r//'
มีความจำเป็น หากไม่มีพวกมันเชลล์จะตีความ\r
ว่าเป็น escape + r และลดลงเป็นธรรมดาr
และลบตัวเล็กr
ทั้งหมด นั่นเป็นเหตุผลที่คำตอบข้างต้นในปี 2009 โดยRobไม่ทำงาน
และการเพิ่ม/g
ตัวดัดแปลงทำให้มั่นใจได้ว่าแม้\r
จะมีหลาย ๆ ตัวจะถูกลบออกและไม่เพียง แต่ตัวแรกเท่านั้น
มีโปรแกรมอรรถประโยชน์ที่เรียกว่าdos2unixที่มีอยู่ในหลาย ๆ ระบบและสามารถติดตั้งได้ง่ายที่สุด
sed -i s/\r// <filename>
หรือ somesuch เห็นหรือความมั่งคั่งของข้อมูลที่มีอยู่บนเว็บเกี่ยวกับการใช้man sed
sed
สิ่งหนึ่งที่ชี้ให้เห็นคือความหมายที่แม่นยำของ "การคืนรถ" ข้างต้น หากคุณหมายถึงอักขระควบคุมอย่างเดียว "carriage return" ดังนั้นรูปแบบด้านบนนั้นถูกต้อง หากคุณหมายถึงโดยทั่วไปแล้ว CRLF (การขึ้นบรรทัดใหม่และการป้อนบรรทัดซึ่งเป็นวิธีการใช้งานตัวดึงข้อมูลบรรทัดใน Windows) คุณอาจต้องการเปลี่ยน\r\n
แทน ฟีดเปลือยสาย (ขึ้นบรรทัดใหม่) ใน Linux / Unix \n
มี
หากคุณเป็นผู้ใช้ Vi คุณสามารถเปิดไฟล์และลบ carriage return ได้ด้วย:
:%s/\r//g
หรือกับ
:1,$ s/^M//
โปรดทราบว่าคุณควรพิมพ์ ^ M โดยกด ctrl-v และ ctrl-m
^M
-s เลย การได้รับสิ่งนี้คือการกดแป้นจำนวนหนึ่งซึ่งไม่ใช่สิ่งที่เป็นกลุ่มสำหรับ;) ฉันแค่ไปหาsed -i
และจากนั้น `-e / \ r $ // g 'เพื่อ จำกัด การลบไปยัง CRs ที่ EOL
อีกวิธีแก้ปัญหา ... เพราะมีอีกหนึ่งเสมอ:
perl -i -pe 's/\r//' filename
เป็นเรื่องที่ดีเพราะมันอยู่ในสถานที่และทำงานได้ในทุกรสชาติของยูนิกซ์ / ลินุกซ์ที่ฉันเคยทำงานด้วย
มีคนอื่นแนะนำdos2unix
และฉันก็ขอแนะนำเช่นกัน ฉันแค่ให้รายละเอียดเพิ่มเติม
หากติดตั้งแล้วให้ข้ามไปยังขั้นตอนถัดไป หากยังไม่ได้ติดตั้งฉันขอแนะนำให้ติดตั้งผ่านyum
เช่น:
yum install dos2unix
จากนั้นคุณสามารถใช้มันเช่น:
dos2unix fileIWantToRemoveWindowsReturnsFrom.txt
หากคุณใช้ระบบปฏิบัติการ (เช่น OS X) ที่ไม่มีdos2unix
คำสั่ง แต่มีตัวแปล Python (เวอร์ชัน 2.5+) คำสั่งนี้จะเทียบเท่ากับdos2unix
คำสั่ง:
python -c "import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))"
dos2unix
จับทั้งสองนี้ชื่อไฟล์บนบรรทัดคำสั่งเช่นเดียวกับท่อและเปลี่ยนเส้นทางเช่นเดียวกับ หากคุณเพิ่มบรรทัดนี้ในไฟล์ ~ / .bashrc ของคุณ (หรือไฟล์โปรไฟล์ที่เทียบเท่าสำหรับเชลล์อื่น ๆ ):
alias dos2unix="python -c \"import sys; import fileinput; sys.stdout.writelines(line.replace('\r', '\n') for line in fileinput.input(mode='rU'))\""
... ครั้งต่อไปที่คุณเข้าสู่ระบบ (หรือเรียกใช้source ~/.bashrc
ในเซสชันปัจจุบัน) คุณจะสามารถใช้dos2unix
ชื่อบนบรรทัดคำสั่งในลักษณะเดียวกับในตัวอย่างอื่น ๆ
นี่คือสิ่งที่
%0d
คืออักขระการรับคืน เพื่อให้เข้ากันได้กับ Unix เราจำเป็นต้องใช้คำสั่งด้านล่าง
dos2unix fileName.extension fileName.extension
ลองใช้วิธีนี้เพื่อแปลงไฟล์ dos เป็นไฟล์ unix:
ไฟล์ fromdos
สำหรับ UNIX ... ฉันสังเกตเห็นว่า dos2unix นำส่วนหัว Unicode ออกจากไฟล์ของฉัน UTF-8 ภายใต้ git bash (Windows) สคริปต์ต่อไปนี้ดูเหมือนว่าจะทำงานได้ดี มันใช้ sed โปรดทราบว่าจะลบ carriage-return ที่ปลายบรรทัดและสงวนส่วนหัวของ Unicode
#!/bin/bash
inOutFile="$1"
backupFile="${inOutFile}~"
mv --verbose "$inOutFile" "$backupFile"
sed -e 's/\015$//g' <"$backupFile" >"$inOutFile"
หากคุณใช้สภาพแวดล้อม X และมีการแก้ไขที่เหมาะสม (รหัสสตูดิโอภาพ) จากนั้นฉันจะทำตามคำแนะนำ:
Visual Studio Code: วิธีแสดงการสิ้นสุดบรรทัด
เพียงไปที่มุมขวาล่างของหน้าจอรหัสสตูดิโอภาพจะแสดงทั้งการเข้ารหัสไฟล์และการสิ้นสุดของบรรทัดตามด้วยไฟล์เพียงแค่คลิกง่ายๆคุณก็สามารถสลับไปมาได้
เพียงใช้รหัสภาพแทนแผ่นจดบันทึก ++ บนสภาพแวดล้อม linux และคุณพร้อมแล้ว
Notepad++
คำสั่งของไปยังEdit / EOL Conversion / Unix (LF)
บนระบบ Windows ของคุณก่อนที่จะคัดลอกไฟล์ไปยังระบบ Linux ของคุณ
\r
บนระบบ UNIX ใด ๆ :โซลูชันที่มีอยู่ส่วนใหญ่ในคำถามนี้มีเฉพาะ GNU และจะไม่ทำงานบน OS X หรือ BSD โซลูชันด้านล่างควรทำงานกับระบบ UNIX อื่น ๆ อีกมากมายและในเชลล์ใด ๆ จากtcsh
ถึงsh
แต่ยังคงใช้ได้แม้ใน GNU / Linux ด้วยเช่นกัน
ผ่านการทดสอบบน OS X, OpenBSD และ NetBSD ในtcsh
และใน Debian GNU / Linux bash
ใน
sed
:ในtcsh
OS X sed
ข้อมูลโค้ดต่อไปนี้สามารถใช้ร่วมกันได้printf
เนื่องจากไม่ใช้sed
หรือecho
จัดการ\r
ในลักษณะพิเศษอย่างที่ GNU ทำ:
sed `printf 's/\r$//g'` input > output
tr
:ตัวเลือกอื่นคือtr
:
tr -d '\r' < input > output
sed
และtr
:มันจะปรากฏขึ้นเพื่อtr
รักษาการขาดบรรทัดใหม่ที่ต่อท้ายจากอินพุตไฟล์ขณะที่sed
ใน OS X และ NetBSD (แต่ไม่ใช่ใน OpenBSD หรือ GNU / Linux) จะแทรกบรรทัดขึ้นบรรทัดใหม่ที่ท้ายสุดของไฟล์แม้ว่าอินพุตจะหายไปก็ตาม ต่อท้าย\r
หรือ\n
ท้ายไฟล์
ต่อไปนี้เป็นตัวอย่างการทดสอบที่สามารถใช้เพื่อให้แน่ใจว่าระบบของคุณใช้printf
และhexdump -C
; หรือod -c
อาจใช้หากระบบของคุณหายไป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
%
ฉันใช้ไพ ธ อนมันนี่รหัสของฉัน;
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)
แม้ว่าจะเป็นโพสต์ที่เก่ากว่าเมื่อเร็ว ๆ นี้ฉันเจอปัญหาเดียวกัน เนื่องจากฉันมีไฟล์ทั้งหมดที่จะเปลี่ยนชื่อภายใน / tmp / blah_dir / เนื่องจากแต่ละไฟล์ในไดเรกทอรีนี้มีอักขระ "/ r" ต่อท้าย (แสดง "?" ในตอนท้ายของไฟล์) ดังนั้นการทำแบบสคริปต์จึงเป็นสิ่งที่ฉันคิดได้เท่านั้น
ฉันต้องการบันทึกไฟล์สุดท้ายด้วยชื่อเดียวกัน (โดยไม่ต้องใส่อักขระใด ๆ ) ด้วยความใจเย็นปัญหาคือชื่อไฟล์เอาต์พุตที่ฉันต้องการพูดถึงอย่างอื่น (ซึ่งฉันไม่ต้องการ)
ฉันลองตัวเลือกอื่น ๆ ตามที่แนะนำที่นี่ (ไม่ถือว่า dos2unix เนื่องจากข้อ จำกัด บางอย่าง) แต่ใช้งานไม่ได้
ฉันลองด้วย "awk" ในที่สุดซึ่งทำงานที่ฉันใช้ "\ r" เป็นตัวคั่นและนำส่วนแรก :
เคล็ดลับคือ:
echo ${filename}|awk -F"\r" '{print $1}'
ตัวอย่างสคริปต์ด้านล่างฉันใช้ (ที่ฉันมีไฟล์ทั้งหมดมี "\ r" เป็นตัวอักษรต่อท้ายที่ path / tmp / blah_dir /) เพื่อแก้ไขปัญหาของฉัน:
cd /tmp/blah_dir/
for i in `ls`
do
mv $i $(echo $i | awk -F"\r" '{print $1}')
done
หมายเหตุ:ตัวอย่างนี้ไม่แม่นยำมากแม้ว่าใกล้กับสิ่งที่ฉันทำงาน (กล่าวถึงที่นี่เพียงเพื่อให้ความคิดที่ดีขึ้นเกี่ยวกับสิ่งที่ฉันทำ)
ฉันสร้างเชลล์สคริปต์นี้เพื่อลบอักขระ \ r มันทำงานได้ในโซลาริสและหมวกแดง:
#!/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
คุณสามารถทำได้:
$ echo $(cat input) > output
a * b
...