如何将多行输出连接到一行?


157

如果运行命令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 2013年


问题与只有一票(一万两千张)的帖子重复了68票(一万四千张)?这是不对的。
kenorb

Answers:


230

使用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
通过这种方法,最终您会得到一个不需要的空间。
索林

1
您需要echo ""在末尾添加以在提示文本之前添加新行。
nexayq

1
效果很好,但是我不希望分隔符显示在最后一个条目上。例如,根据您的情况",它显示为one" two" three",但是我希望它显示为one" two" three。请注意,最后三个没有括号。有任何想法吗?
oink

2
@oink,您可以将结果sed '$s/..$//'传送到其中以删除最后一行的最后2个字符。
克里斯·西摩

3
如果您不希望用任何内容替换换行符,则需要使用该--delete选项,因为默认情况下需要两个参数。例如tr --delete '\n'
伊利亚·林恩

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

echo不带引号的bash中删除回车符,制表符和多个空格

echo $(cat file)

8
在这里,答案被严重低估了,这确实很简单,并且像魅力一样,还带有尾随换行符。
Dangercrow

如果使用,这尤其整齐IFS="$(printf '\n\t')"
aggsol

5
或者只是echo $(<file)...使用echo不仅比using更整洁tr '\n' ' ',而且还更好(请考虑\r\n行结尾)。您可以说IFS=$'\n\t'
@aggsol

没有空间怎么办?
DimiDak

22

这可能就是你想要的

cat file | grep pattern | paste -sd' '

至于您的编辑,我不确定这意味着什么,也许是这样吗?

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

(这假定~不会在中发生file


2
@Stephan无需假设cat file它将实际上是cat,甚至是文件。(我只是保留了与问题无关的那部分,因此保持不变)
sehe 2015年

5

这是一个以逗号分隔输出的示例。您可以使用所需的任何分隔符来替换逗号。

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

产生:

1,2,3,4,5

3

这是使用ex编辑器Vim的一部分)的方法:

  • Ĵ OIN所有行和p RINT到标准输出:

    $ ex +%j +%p -scq! file
  • Ĵ 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),然后对每个波浪号(flag g)进行替换。


0

可能最好的方法是使用“ awk”工具,它将生成输出到一行

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

它将使用空格分隔符将所有行合并为一


您不需要,{print}因为它是awk的默认操作。
鲜明

0

在红帽linux上,我只使用echo:

回声$ {cat / some / file / name)

这样我就可以在一行上找到文件的所有记录。


1
这已是2015年的答案。您正在复制此答案。请在发布自己的答案之前先阅读答案,特别是当问题已存在7年并且已经有8个答案时。
Mickael B.
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.