วิธีการต่อผลลัพธ์หลายบรรทัดเข้าด้วยกันเป็นหนึ่งบรรทัด?


158

ถ้าฉันรันคำสั่งcat file | grep patternฉันจะได้ผลลัพธ์หลายบรรทัด คุณต่อแถวทั้งหมดเป็นหนึ่งบรรทัดได้อย่างไรโดยแทนที่แต่ละบรรทัด"\n"ด้วย"\" "(ลงท้ายด้วย"ช่องว่าง)

cat file | grep pattern | xargs sed s/\n/ /g ไม่ทำงานสำหรับฉัน


โดยวิธีการ: (1) คุณต้องใส่sedสคริปต์ของคุณในเครื่องหมายคำพูดเดียวเพื่อให้ Bash ไม่ยุ่งกับมัน (ตั้งแต่การsed s/\n/ /gโทรที่sedมีสองอาร์กิวเมนต์คือs/n/และ/g); (2) ตั้งแต่คุณต้องการผลลัพธ์ของcat file | grep patternการเป็นผู้ป้อนข้อมูลไปยังsedไม่ได้ข้อโต้แย้งที่จะsedคุณจะต้องกำจัดxargs; และ (3) ไม่จำเป็นสำหรับcatที่นี่เนื่องจากgrepสามารถใช้ชื่อไฟล์เป็นอาร์กิวเมนต์ที่สอง grep pattern file | sed 's/\n/ /g'ดังนั้นคุณควรมีความพยายาม (ในกรณีนี้มันจะไม่ทำงานด้วยเหตุผลที่ได้รับจากลิงก์ด้านบน แต่ตอนนี้คุณรู้อนาคตแล้ว)
ruakh


คำถามที่มี 68 คะแนน (140k การดู) ทำซ้ำกับโพสต์ที่มีเพียง 1 โหวต (12k views)? มันไม่ถูกต้อง
kenorb

คำตอบ:


231

ใช้tr '\n' ' 'เพื่อแปลอักขระบรรทัดใหม่ทั้งหมดเป็นช่องว่าง:

$ grep pattern file | tr '\n' ' '

หมายเหตุ: grepอ่านไฟล์catเชื่อมไฟล์ต่าง ๆ อย่าcat file | grep!

แก้ไข:

trสามารถจัดการการแปลตัวอักษรเดียวเท่านั้น คุณสามารถใช้awkเพื่อเปลี่ยนตัวแยกบันทึกผลลัพธ์เช่น:

$ grep pattern file | awk '{print}' ORS='" '

สิ่งนี้จะเปลี่ยน:

one
two 
three

ถึง:

one" two" three" 

3
คุณจบด้วยพื้นที่ที่ไม่พึงประสงค์ในตอนท้ายด้วยวิธีนี้
sorin

1
คุณต้องเพิ่มecho ""ในตอนท้ายเพื่อเพิ่มบรรทัดใหม่ก่อนที่จะมีข้อความแจ้ง
nexayq

1
มันใช้งานได้ดี แต่ฉันไม่ต้องการให้ตัวแยกปรากฏขึ้นในรายการสุดท้าย ตัวอย่างเช่นคุณ"แสดงขึ้นมาเหมือนone" two" three"กัน แต่ฉันต้องการให้ปรากฏเหมือนone" two" threeกัน หมายเหตุสามอันสุดท้ายไม่มีวงเล็บ ความคิดใด ๆ
oink

2
@oink คุณสามารถไพพ์ผลลัพธ์เป็นsed '$s/..$//'ลบอักขระ 2 ตัวสุดท้ายในบรรทัดสุดท้าย
Chris Seymour

3
หากคุณต้องการแทนที่บรรทัดใหม่ด้วยอะไรคุณต้องใช้--deleteตัวเลือกตามค่าเริ่มต้นที่คาดว่าจะมีสองอาร์กิวเมนต์ tr --delete '\n'เช่น
Elijah Lynn

69

ไปป์xargsไลน์เพื่อเชื่อมต่อแต่ละบรรทัดของเอาต์พุตกับบรรทัดเดียวโดยมีช่องว่าง:

grep pattern file | xargs

หรือคำสั่งใด ๆ เช่น ls | xargs. ขีด จำกัด ดีฟอลต์ของxargsเอาต์พุตคือ ~ 4096 ตัวอักษร แต่สามารถเพิ่มได้เช่น xargs -s 8192.


| tr '\n' ' 'ไม่ทำงานสำหรับฉันเมื่อถูกเรียกผ่านphp execฟังก์ชั่น มันไม่สนใจ tr และเพิ่งให้นัดสุดท้ายจาก grep | xargsทำงาน
Adarsha

3
วิธีนี้ยังมีข้อได้เปรียบที่ว่า 'กิน' ช่องว่างจากอินพุต +1
Rene

55

ใน bash ที่echoไม่มีเครื่องหมายคำพูดให้นำ carriage return, tab และหลายช่องว่าง

echo $(cat file)

8
คำตอบที่ถูกประเมินค่าต่ำเกินไปอย่างรุนแรงนี่เป็นเรื่องง่ายและใช้งานได้ดีอย่างมีเสน่ห์พร้อมกับการขึ้นบรรทัดใหม่ตามมาด้วย
Dangercrow

นี่เป็นระเบียบโดยเฉพาะถ้าคุณใช้IFS="$(printf '\n\t')"
aggsol

5
หรือเพียงแค่echo $(<file)... การใช้เสียงสะท้อนไม่ได้เป็นเพียงเสียงมากกว่าการใช้tr '\n' ' 'แต่ยังดีกว่า (คิดว่าการ\r\nจบบรรทัด) @aggsol คุณสามารถพูดได้IFS=$'\n\t'
ทำให้เป็นเรื่องปกติ

ถ้าไม่มีที่ว่างล่ะ
DimiDak

22

นี่อาจเป็นสิ่งที่คุณต้องการ

cat file | grep pattern | paste -sd' '

สำหรับการแก้ไขของคุณฉันไม่แน่ใจว่ามันแปลว่าอะไร

cat file | grep pattern | paste -sd'~' | sed -e 's/~/" "/g'

(สิ่งนี้ถือว่า~ไม่มีในfile)


2
@ สเตฟานไม่จำเป็นต้องคิดว่ามันcat fileจะเป็นจริงcatหรือแม้แต่ไฟล์ (ฉันเหลือเพียงส่วนหนึ่งที่ไม่เปลี่ยนแปลงเพราะมันเป็นอะไรที่ไม่เกี่ยวข้องกับคำถาม)
sehe

5

นี่คือตัวอย่างที่สร้างเอาต์พุตแยกจากคอมมา คุณสามารถแทนที่เครื่องหมายจุลภาคด้วยตัวคั่นที่คุณต้องการ

cat <<EOD | xargs | sed 's/ /,/g'
> 1
> 2
> 3
> 4
> 5
> EOD

ผลิต:

1,2,3,4,5

3

นี่คือวิธีการใช้exโปรแกรมแก้ไข (ส่วนหนึ่งของVim ):

  • J oin ทุกบรรทัดและp rint ไปยังเอาต์พุตมาตรฐาน:

    $ ex +%j +%p -scq! file
  • J oin ทุกบรรทัดในสถานที่ (ในไฟล์):

    $ ex +%j -scwq file

    หมายเหตุ: สิ่งนี้จะเชื่อมโยงทุกบรรทัดภายในไฟล์ด้วยตนเอง!


2

วิธีที่เร็วและง่ายที่สุดที่ฉันรู้ในการแก้ปัญหานี้:

เมื่อเราต้องการแทนที่อักขระบรรทัดใหม่ \n ด้วยช่องว่าง :

xargs < file

xargsมีข้อ จำกัด เกี่ยวกับจำนวนอักขระต่อบรรทัดและจำนวนอักขระทั้งหมดรวมกัน แต่เราสามารถเพิ่มได้ รายละเอียดสามารถพบได้โดยใช้คำสั่งนี้: xargs --show-limitsและแน่นอนในคู่มือ:man xargs

เมื่อเราต้องการแทนที่ตัวละครหนึ่งด้วยอีกตัวหนึ่งตัว :

tr '\n' ' ' < file

เมื่อเราต้องการแทนที่หนึ่งอักขระด้วยอักขระหลายตัว :

tr '\n' '~' < file | sed s/~/many_characters/g

อันดับแรกเราแทนที่อักขระบรรทัดใหม่\nสำหรับตัวหนอน~(หรือเลือกอักขระที่ไม่ซ้ำกันอีกตัวหนึ่งซึ่งไม่ปรากฏในข้อความ) จากนั้นเราจะแทนที่อักขระตัวหนอนด้วยอักขระอื่น ๆ ( many_characters) และเราดำเนินการแทนตัวหนอน (ธงg)


0

อาจเป็นวิธีที่ดีที่สุดในการใช้เครื่องมือ 'awk' ซึ่งจะสร้างผลลัพธ์เป็นหนึ่งบรรทัด

$ awk ' /pattern/ {print}' ORS=' ' /path/to/file

มันจะรวมทุกบรรทัดเป็นหนึ่งเดียวด้วยตัวคั่นช่องว่าง


คุณไม่ต้องการ{print}เนื่องจากเป็นการกระทำเริ่มต้นของ awk
สิ้นเชิง

0

นี่เป็นอีกวิธีการง่ายๆที่ใช้awk:

# cat > file.txt
a
b
c

# cat file.txt | awk '{ printf("%s ", $0) }'
a b c

นอกจากนี้หากไฟล์ของคุณมีคอลัมน์สิ่งนี้จะช่วยให้เชื่อมโยงคอลัมน์บางคอลัมน์ได้ง่าย:

# cat > cols.txt
a b c
d e f

# cat cols.txt | awk '{ printf("%s ", $2) }'
b e

-1

บน linux hat สีแดงฉันแค่ใช้ echo:

echo $ (cat / some / file / name)

นี่ให้เรคคอร์ดทั้งหมดของไฟล์ในบรรทัดเดียว


2
นี่เป็นคำตอบแล้วในปี 2015 คุณแค่ทำซ้ำคำตอบนี้ โปรดอ่านคำตอบก่อนโพสต์ของคุณเองโดยเฉพาะเมื่อคำถามมีอายุ 7 ปีและมี 8 คำตอบอยู่แล้ว
Mickael B.
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.