如何从命令行将每两行合并成一行?
我有一个以下格式的文本文件。 第一行是“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 我需要和键一样的值。 所以输出应该是这样的…
 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 
如果我可以使用一些分隔符如$或KEY 4048:1736string3,会更好
如何将两行合并成一行?
AWK:
 awk 'NR%2{printf "%s ",$0;next;}1' yourFile 
请注意,输出结尾处有一个空行。
SED:
 sed 'N;s/\n/ /' yourFile 
  paste这个工作是好的: 
 paste -d " " - - < filename 
杀死一条狗的方法比悬挂更多。 [1]
 awk '{key=$0; getline; print key ", " $0;}' 
把你喜欢的任何分隔符放在引号内。
参考文献:
- 最初的“皮肤猫的方法很多”,恢复到一个较旧的,也可能是起源的expression,也没有任何关系与宠物。
替代sed,awk,grep:
 xargs -n2 -d'\n' 
这是最好的,当你想要joinN行,你只需要空格分隔输出。
 我原来的答案是xargs -n2 ,它在单词而不是线条上分开。  -d可以用来分割任何单个字符的input。 
这里是我在bash中的解决scheme:
 while read line1; do read line2; echo "$line1, $line2"; done < data.txt 
虽然看起来以前的解决scheme是可行的,但如果在文档中出现单个exception,输出将会变成碎片。 下面有点安全。
 sed -n '/KEY/{ N s/\n/ /p }' somefile.txt 
 这是awk另一种方法: 
 awk 'ORS=NR%2?FS:RS' file 
 $ 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 
 $ 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 
正如Ed Morton在评论中指出的那样,最好在安全性和可携带性方面增加支架。
 awk '{ ORS = (NR%2 ? FS : RS) } 1' file 
  ORS代表输出logging分隔符。 我们在这里做的是使用存储行号的NR来testing一个条件。 如果NR的模是一个真值(> 0),那么我们将输出字段分隔符设置为FS (字段分隔符)的值,默认为空格,否则我们分配换行符的RS (logging分隔符)的值。 
 如果你想添加,作为分隔符,然后使用以下内容: 
 awk '{ ORS = (NR%2 ? "," : RS) } 1' file 
“ex”是一个脚本行编辑器,与sed,awk,grep等在同一个家族中。我想这可能是你正在寻找的东西。 许多现代的vi克隆/后继者也有vi模式。
  ex -c "%g/KEY/j" -c "wq" data.txt 
这表示对于每一行,如果它匹配“KEY”,则执行以下行中的某个行。 在这个命令完成之后(针对所有行),发出一个wRite并且把它给你。
如果Perl是一个选项,你可以尝试:
 perl -0pe 's/(.*)\n(.*)\n/$1 $2\n/g' file.txt 
你可以像这样使用awk来结合2对线:
 awk '{ if (NR%2 != 0) line=$0; else {printf("%s %s\n", line, $0); line="";} } \ END {if (length(line)) print line;}' flle 
你也可以使用下面的vi命令:
 :%g/.*/j 
 nawk '$0 ~ /string$/ {printf "%s ",$0; getline; printf "%s\n", $0}' filename 
这读作为
 $0 ~ /string$/ ## matches any lines that end with the word string printf ## so print the first line without newline getline ## get the next line printf "%s\n" ## print the whole line and carriage return 
在我需要结合两条线(为了更容易处理)的情况下,但是允许数据超过特定的情况,我发现这是有用的
data.txt中
 string1=x string2=y string3 string4 
cat data.txt | nawk'$ 0〜/ string1 = / {printf“%s”,$ 0; 函数getline; printf“%s \ n”,$ 0; getline} {print}'> converted_data.txt
输出结果如下所示:
converted_data.txt
 string1=x string2=y string3 string4 
另一个使用vim的解决scheme(仅供参考)。
解决scheme1 :
 在vim vim filename打开文件,然后执行命令:% normal Jj 
这个命令退出容易理解:
- %:对于所有的行,
- 正常:执行正常命令
- Jj:执行join命令,然后跳转到下一行
 之后,保存文件并退出:wq 
解决scheme2 :
 在shell中执行命令vim -c ":% normal Jj" filename ,然后保存该文件并退出:wq 。 
最简单的方法是:
- 删除偶数行并将其写入临时文件1中。
- 删除奇数行并将其写入临时文件2中。
- 将两个文件合并为一个通过使用粘贴命令与-d(意味着删除空间)
 sed '0~2d' file > 1 && sed '1~2d' file > 2 && paste -d " " 1 2 
 perl -0pE 's{^KEY.*?\K\s+(\d+)$}{ $1}msg;' data.txt > data_merged-lines.txt 
  -0吞下整个文件,而不是逐行阅读; 
  pE用循环打包代码并打印输出,详见http://perldoc.perl.org/perlrun.html ; 
  ^KEY在行开头匹配“KEY”,之后是任何事物( .*? )的非贪婪匹配 
- 任何种类的一个或多个空格,包括换行符;
-  一个或多个数字(\d+),我们捕获并稍后重新插入为$1;
 之后是$行的结尾。 
  \K方便地将其左侧的所有内容从replace中排除,因此{ $1}仅replace1-2个序列,请参阅http://perldoc.perl.org/perlre.html 。 
一个更通用的解决scheme(允许连接多个后续行)作为shell脚本。 这在每个之间添加了一条线,因为我需要可见性,但是这很容易修复。 这个例子是“关键”行结束的地方:没有其他的行。
 #!/bin/bash # # join "The rest of the story" when the first line of each story # matches $PATTERN # Nice for looking for specific changes in bart output # PATTERN='*:'; LINEOUT="" while read line; do case $line in $PATTERN) echo "" echo $LINEOUT LINEOUT="$line" ;; "") LINEOUT="" echo "" ;; *) LINEOUT="$LINEOUT $line" ;; esac done 
尝试以下行:
 while read line1; do read line2; echo "$line1 $line2"; done <old.txt>new_file 
把分隔符放在中间
 "$line1 $line2"; 
 例如,如果分隔符是|  , 然后: 
 "$line1|$line2"; 
 你可以像这样使用xargs : 
 xargs -a file