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

Posted

技术标签:

【中文标题】如何将多行输出连接到一行?【英文标题】:How to concatenate multiple lines of output to one line? 【发布时间】:2013-03-12 21:19:02 【问题描述】:

如果我运行命令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'。 (在这种情况下,由于上述链接中给出的原因,它不会起作用,但现在你知道未来了。) 类似于“***.com/questions/2764051/…” 68 票(140k 浏览)的问题与只有 1 票(12k 浏览)的帖子重复?这是不对的。 见:Should I flag a question as duplicate if it has received better answers? 【参考方案1】:

使用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" 

【讨论】:

用这种方法最后会得到一个不需要的空间。 提示文字前需要在末尾添加echo "",以添加新行。 这很好用,但是我不希望分隔符出现在最后一个条目上。例如,根据您的",它显示为one" two" three",但我希望它显示为one" two" three。注意最后三个没有括号。有什么想法吗? @oink 您可以将结果通过管道传输到 sed '$s/..$//' 以删除最后一行的最后 2 个字符。 如果你想用空替换换行符,你需要使用--delete 选项,因为默认需要两个参数。例如tr --delete '\n'.【参考方案2】:

这可能是你想要的

cat file | grep pattern | paste -sd' '

至于您的编辑,我不确定它是什么意思,也许是这个?

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

(假设~ 不会出现在file 中)

【讨论】:

@Stephan 没有必要假设cat file 实际上是cat,甚至是一个文件。 (我只是保持那部分不变,因为它与问题无关)【参考方案3】:

通过管道输出到xargs 会将输出的每一行连接到带有空格的单行:

grep pattern file | xargs

或任何命令,例如。 ls | xargsxargs 输出的默认限制是 ~4096 个字符,但可以通过例如增加。 xargs -s 8192.

grepxargs

【讨论】:

| tr '\n' ' ' 在通过php exec 函数调用时对我不起作用。它忽略了 tr,只给出了 grep 的最后一场比赛。 | xargs 工作。 此解决方案还有一个优势,即它会从输入中“吃掉”空格。 +1【参考方案4】:

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

echo $(cat file)

【讨论】:

这里的答案被严重低估了,这真的很简单,而且效果很好,还有一个尾随换行符。 如果您使用IFS="$(printf '\n\t')",这尤其整洁 或者只是echo $(<file) ...使用echo不仅比使用tr '\n' ' '更简洁,而且更好(想想\r\n行尾)。 @aggsol 你可以说IFS=$'\n\t' 没有空格怎么办? 在 Unix 系统上工作得非常好 - 但 Windows(例如 MSYS2 / Git Bash)的行为方式不同 - 可能是其他系统的工作方式也不同。 awk 对我来说跨平台工作最可靠。【参考方案5】:

这里是使用ex editor(Vim的一部分)的方法:

J输入所有行并p输出到标准输出:

$ ex +%j +%p -scq! file

J就地插入所有行(在文件中):

$ ex +%j -scwq file

注意:这将连接文件本身中的所有行!

【讨论】:

【参考方案6】:

可能最好的方法是使用 'awk' 工具,它会在一行中生成输出

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

它将所有行合并为一个带有空格分隔符的行

【讨论】:

你不需要print,因为它是awk的默认操作。【参考方案7】:

这是一个以逗号分隔输出的示例。你可以用你需要的任何分隔符替换逗号。

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

产生:

1,2,3,4,5

【讨论】:

【参考方案8】:

我知道解决这个问题的最快和最简单的方法:

当我们想要替换换行符 \n 用空格

xargs < file

xargs 对每行字符数和所有字符组合的数量有自己的限制,但我们可以增加它们。可以通过运行以下命令找到详细信息:xargs --show-limits,当然也可以在手册中找到:man xargs

当我们想要将一个字符替换为另一个正好是一个字符时

tr '\n' ' ' < file

当我们想用多个字符替换一个字符

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

首先,我们将换行符 \n 替换为波浪号 ~(或选择文本中不存在的另一个唯一字符),然后我们将波浪号替换为任何其他字符 (many_characters),然后我们这样做每个波浪号(标志g)。

【讨论】:

【参考方案9】:

在 red hat linux 上我只使用 echo :

echo $(cat /some/file/name)

这给了我一个文件的所有记录在一行上。

【讨论】:

这已在 2015 年得到回答。您只是在复制 this answer。请在发布您自己的答案之前阅读答案,特别是当问题是 7 岁并且已经有 8 个答案时。【参考方案10】:

这是另一个使用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

【讨论】:

【参考方案11】:

我喜欢xargs 解决方案,但如果不折叠空格很重要,那么可以这样做:

sed ':b;N;$!bb;s/\n/ /g'

这将替换空格的换行符,而不像 tr '\n' ' ' 那样替换最后一行终止符。

这还允许您使用除空格之外的其他连接字符串,如逗号等,这是xargs 无法做到的:

$ seq 1 5 | sed ':b;N;$!bb;s/\n/,/g'
1,2,3,4,5

【讨论】:

以上是关于如何将多行输出连接到一行?的主要内容,如果未能解决你的问题,请参考以下文章

Oracle - 将一行或多行连接到不同的结果列

将一行连接到Mysql中另一个表中的多行

如何将python连接到sqlite3并一次填充多行

Wordpress 用户和用户元 - 将一个表中的多行连接到另一个表中的一行

如何在 Microsoft SQL Server Management Studio 中将多行合并为一行,用逗号分隔

如何使用套接字将Arduino连接到C ++?