sha*_*nuo 137 bash awk grep sed
我有一个文本文件,格式如下.第一行是"KEY",第二行是"VALUE".
KEY 4048:1736 string
3
KEY 0:1772 string
1
KEY 4192:1349 string
1
KEY 7329:2407 string
2
KEY 0:1774 string
1
Run Code Online (Sandbox Code Playgroud)
我需要与键相同的行中的值.所以输出应该是这样的......
KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1
Run Code Online (Sandbox Code Playgroud)
如果我可以像$
或使用一些分隔符会更好,
:
KEY 4048:1736 string , 3
Run Code Online (Sandbox Code Playgroud)
如何将两行合并为一行?
gle*_*man 220
paste
对这项工作有好处:
paste -d " " - - < filename
Run Code Online (Sandbox Code Playgroud)
Ken*_*ent 169
AWK:
awk 'NR%2{printf "%s ",$0;next;}1' yourFile
Run Code Online (Sandbox Code Playgroud)
请注意,输出结尾处有一个空行.
SED:
sed 'N;s/\n/ /' yourFile
Run Code Online (Sandbox Code Playgroud)
nno*_*nog 34
替代sed,awk,grep:
xargs -n2 -d'\n'
Run Code Online (Sandbox Code Playgroud)
当你想加入N行并且只需要空格分隔输出时,这是最好的.
我原来的答案是xargs -n2
单词而不是单词.-d
可用于按任何单个字符拆分输入.
gho*_*oti 26
杀死狗的方法多于悬挂的方法.[1]
awk '{key=$0; getline; print key ", " $0;}'
Run Code Online (Sandbox Code Playgroud)
在引号内放置你喜欢的任何分隔符.
参考文献:
Hai*_* Vu 11
这是我在bash中的解决方案:
while read line1; do read line2; echo "$line1, $line2"; done < data.txt
Run Code Online (Sandbox Code Playgroud)
J.D*_*.D. 11
虽然看起来先前的解决方案可行,但如果文档中出现单个异常,则输出将变为碎片.下面有点安全.
sed -n '/KEY/{
N
s/\n/ /p
}' somefile.txt
Run Code Online (Sandbox Code Playgroud)
jay*_*ngh 11
这是另一种方式awk
:
awk 'ORS=NR%2?FS:RS' file
Run Code Online (Sandbox Code Playgroud)
$ cat file
KEY 4048:1736 string
3
KEY 0:1772 string
1
KEY 4192:1349 string
1
KEY 7329:2407 string
2
KEY 0:1774 string
1
Run Code Online (Sandbox Code Playgroud)
$ awk 'ORS=NR%2?FS:RS' file
KEY 4048:1736 string 3
KEY 0:1772 string 1
KEY 4192:1349 string 1
KEY 7329:2407 string 2
KEY 0:1774 string 1
Run Code Online (Sandbox Code Playgroud)
正如Ed Morton在评论中指出的那样,最好为安全性和便携性添加括号.
awk '{ ORS = (NR%2 ? FS : RS) } 1' file
Run Code Online (Sandbox Code Playgroud)
ORS
代表输出记录分隔符.我们在这里做的是使用NR
存储行号的条件来测试条件.如果模数为NR
真值(> 0),那么我们将输出字段分隔符设置为FS
(字段分隔符)的值,默认情况下为空格,否则我们分配RS
(记录分隔符)的值为换行符.
如果您希望添加,
为分隔符,请使用以下内容:
awk '{ ORS = (NR%2 ? "," : RS) } 1' file
Run Code Online (Sandbox Code Playgroud)
"ex"是一个可编写脚本的行编辑器,与sed,awk,grep等属于同一个族.我认为它可能就是你要找的东西.许多现代vi克隆/后继者也有vi模式.
ex -c "%g/KEY/j" -c "wq" data.txt
Run Code Online (Sandbox Code Playgroud)
这说的每一行,如果"KEY"匹配执行Ĵ OIN以下行的.该命令完成(对所有线)后,发出W¯¯仪式和q UIT.
您可以像这样使用 awk 来组合两对行:
awk '{ if (NR%2 != 0) line=$0; else {printf("%s %s\n", line, $0); line="";} } \
END {if (length(line)) print line;}' flle
Run Code Online (Sandbox Code Playgroud)
如果可以选择 Perl,您可以尝试:
perl -0pe 's/(.*)\n(.*)\n/$1 $2\n/g' file.txt
Run Code Online (Sandbox Code Playgroud)
另一个使用 vim 的解决方案(仅供参考)。
解决方案1:
在 vim 中打开文件vim filename
,然后执行命令:% normal Jj
这个命令很容易理解:
之后,保存文件并退出 :wq
解决方案2:
在 shell 中执行命令vim -c ":% normal Jj" filename
,然后保存文件并退出:wq
。
glenn jackman 的答案略有不同,使用paste
:如果-d
分隔符选项的值包含多个字符,则一个一个地paste
循环遍历这些字符,并结合-s
选项在处理相同的输入文件时继续执行此操作。
这意味着我们可以使用任何我们想要的分隔符和转义序列\n
来一次合并两行。
使用逗号:
$ paste -s -d ',\n' infile
KEY 4048:1736 string,3
KEY 0:1772 string,1
KEY 4192:1349 string,1
KEY 7329:2407 string,2
KEY 0:1774 string,1
Run Code Online (Sandbox Code Playgroud)
和美元符号:
$ paste -s -d '$\n' infile
KEY 4048:1736 string$3
KEY 0:1772 string$1
KEY 4192:1349 string$1
KEY 7329:2407 string$2
KEY 0:1774 string$1
Run Code Online (Sandbox Code Playgroud)
这不能做的是使用由多个字符组成的分隔符。
作为奖励,如果paste
符合 POSIX,这不会修改文件中最后一行的换行符,因此对于具有奇数行的输入文件,例如
KEY 4048:1736 string
3
KEY 0:1772 string
Run Code Online (Sandbox Code Playgroud)
paste
不会在最后一行添加分隔符:
$ paste -s -d ',\n' infile
KEY 4048:1736 string,3
KEY 0:1772 string
Run Code Online (Sandbox Code Playgroud)