แทนที่ \ n ด้วยบรรทัดใหม่ใน sed portably


23

ฉันสับสนกับ GNU sed, POSIX sedและsedตัวเลือกมากมายของBSD ฉันจะแทนที่ตัวอักษร\nด้วยอักขระขึ้นบรรทัดใหม่โดยใช้ทั้งสามsedประเภทได้อย่างไร


พวกเขามีหลายสิ่งหลายอย่างคุณต้องการรู้ส่วนใด
cuonglm

@Gououc ฉันคิดว่าตอนนี้มันชัดเจน
Avinash Raj

1
คุณได้ดูคำถามนี้หรือไม่?
groxxda

2
สิ่งใดที่คุณต้องการให้เกิดขึ้นกับการป้อนข้อมูลเหมือนfoo\\nbarหรือfoo\\\nbar?
Gilles 'หยุดความชั่วร้าย'

ง่าย foo \\ ในบรรทัดถัดไปมันจะเป็นแถบ
Avinash Raj

คำตอบ:


30
sed 's/\\n/\
/g'

สังเกตว่าแบ็กสแลชก่อนที่จะกดปุ่มย้อนกลับในสตริงการแทนที่


มันใช้งานได้กับ sed ทุกชนิดหรือไม่
Avinash Raj

ฉันเชื่อว่ามันควร; ฉันทดสอบเฉพาะบน Linux โดยใช้เวอร์ชัน gnu
unxnut

11
@AvinashRaj นั่นคือ POSIX และทำงานร่วมกับsedคำสั่งดั้งเดิมใน Unix v7 ในปี 1979 สถานที่เดียวที่อาจไม่สามารถใช้งานได้นั้นคือ POSIX ที่ไม่ได้ใช้งานที่ไม่ได้ใช้งานsedเช่นเดียวกับคนอื่น ๆ ที่ไม่ทำงานใน csh แต่มันเป็นปัญหา csh
Stéphane Chazelas

เนื่องจาก\\nใช้ในส่วนการค้นหาทำไมไม่ใช้\nในการแทนที่ อดีตดูเหมือนจะบ่งบอกถึงหลังที่มีอยู่ กล่าวคือ ทำไมไม่เป็นเช่นนั้น$ echo '1\n2'|sed 's/\\n/\n/g'

ในกรณี\nนี้เป็นตัวอักษรซึ่งหมายความว่ามันจะปรากฏเป็นตัวละครทั้งสอง: abackslash ตามด้วยnและไม่เป็นตัวอักษรขึ้นบรรทัดใหม่เดียว ดังนั้นแบ็กสแลชสองตัวที่ใช้แบ็กสแลชที่แท้จริงแล้วn
unxnut

9

เนื่องจากคุณมีsedคำตอบแบบพกพาอยู่แล้วฉันจะพูดถึงว่าsedมันไม่ค่อยเป็นเครื่องมือที่ดีที่สุดถ้าคุณต้องการจัดการกับการขึ้นบรรทัดใหม่ Perl นั้นเกือบพกพาsedติดตั้งได้ตามค่าเริ่มต้นในระบบ nix ส่วนใหญ่และสามารถจัดการกับสิ่งนี้ได้อย่างง่ายดาย:

printf '%s\n' 'aa\nbb' | perl -pe 's/\\n/\n/g'

อีกทางเลือกที่พกพามากคือawk:

printf '%s\n' 'aa\nbb' | awk  '{gsub("\\\\n","\n")};1'

บน Solaris อย่าลืมใช้ awk มาตรฐานใน / usr / xpg4 / bin หนึ่งใน / bin เป็นอันเก่าแก่และไม่ควรใช้สำหรับสคริปต์ใหม่


ผมว่าawkมีปัญหาที่คล้ายกันพกพา (คือของฉันawkเก่าธรรมดาawk, nawkหรือgawk?) ที่จริงรุ่นในกล่อง Solaris gsub()ของฉันขาด คะแนนของฉันที่นี่มีไว้สำหรับ Perl ( perl -nlawe '...'ประมาณพฤติกรรมอัตโนมัติของawk)
arielCo

2
@ arelCo: สำหรับการawkพกพาติดกับรุ่นawkที่เป็นไปตาม POSIX และใช้คุณสมบัติเหล่านั้นเท่านั้นและคุณควรจะใช้ได้ บน Solaris /usr/xpg4/bin/awkคุณจะพบหนึ่ง
Scrutinizer

@terdon แล้วเรื่องนี้echo "aa\nbb" | awk '{gsub(/\\n/,"\n");}1;'ล่ะ?
Avinash Raj

@arielCo จริงๆแล้ว awk นั้นพกพาได้ง่ายกว่า perl วิธี awk ที่สองของฉันที่ไม่ได้ใช้gsub()ควรทำงานได้ทุกที่ แม้ busybox awkมี
terdon

1
gsub () คือ POSIX (gsub, ถูกเพิ่มใน SVR3.1, POSIX awk ขึ้นอยู่กับ SVR4 โดยมีส่วนเพิ่มเติมไม่กี่ดูที่คู่มือ gawk สำหรับข้อมูลเพิ่มเติม), gensub () เป็นส่วนขยายของ GNU awk ดั้งเดิมยังคงพบว่าเป็น / bin / awk บน Solaris ไม่รองรับ gsub () แต่ไม่รองรับ FS หลายตัวอักษรเช่นกัน
Stéphane Chazelas

1

หากHoldspace ว่างเปล่าคุณสามารถทำได้:

sed '/\\n/G;s/\\n\(.*\)\(.\)/\2\1/;P;D'

... แต่คำตอบของ uxnutนั้นมีทั้งเร็วและง่ายกว่าอยู่แล้วดังนั้นคุณจึงสามารถทำได้ตามที่ต้องการ

ความเป็นไปได้ภายนอกอื่น:

INPUT | sed -n l | while read v ; do printf "${v%?}" ; done

แต่ระวัง ^ ที่แปล\เครื่องหมายแบ็กสแลชสไตล์ C ทั้งหมด- เช่น\backspace \rและ\00eturn และ octals และ whathaveyou



-2

คุณต้องมีวิธีการแก้ปัญหาใน sed และที่ได้รับด้านล่าง แต่ฉันต้องการเพิ่มความเป็นไปได้อีกอย่างที่ IMHO นั้นง่ายขึ้นและเร็วขึ้น

tr -d "\n"

1
สิ่งนี้ทำอะไร ลบบรรทัดใหม่ทั้งหมดออกจากอินพุตหรือไม่
mikeserv

ใช่นั่นคือสิ่งที่มันทำ
jpmuc

5
แต่ ... ทำไม สิ่งนี้เกี่ยวข้องกับคำถามอย่างไร?
mikeserv

1
สิ่งนี้จะลบ "\ n" เมื่อคำถามถามถึงวิธีการแทนที่สตริง "\ n" ด้วยการขึ้นบรรทัดใหม่จริง
spuder
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.