如何将多行输出连接到一行?
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 | xargs
。 xargs
输出的默认限制是 ~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
【讨论】:
以上是关于如何将多行输出连接到一行?的主要内容,如果未能解决你的问题,请参考以下文章
Wordpress 用户和用户元 - 将一个表中的多行连接到另一个表中的一行