为了连接连续的行,我发现这是由Kanaka和GhostDog74发布的:
while read line; do echo -n $line; [ "${i}" ] && echo && i= || i=1 ; done < File
效果很好,但我想修改它以连接当前行和超出它的第4行,如下所示:
line1
line2
line3
line4
line5
line6
line7
line1,line4
line2,line5
line3,line6
etc.
非常感谢任何帮助。
答案 0 :(得分:2)
printf "%s\n" line1 line2 line3 line4 line5 line6 line7 line8 |
awk 'NR > 3 {print prev3 ", " $0} {prev3=prev2; prev2=prev1; prev1=$0} '
产生
line1, line4
line2, line5
line3, line6
line4, line7
line5, line8
答案 1 :(得分:1)
如果数据位于文件'<data file>'
:
tail -n +4 <data file> | paste -d ',' <data file> - | head -n -3
'tail'
命令删除'<data file>'
的前3行'paste'
命令将'<data file>'
与结果'tail'
连接在一起,使用分隔符','
,'head'
命令会移除'paste'
中'tail'
中不使用任何内容的最后3行。答案 2 :(得分:1)
此外,在纯粹的bash中不需要文件:
<command that output something> | (read l1; read l2; read l3; while read l4; do echo "$l1,$l4"; l1=$l2; l2=$l3; l3=$l4; done)
修改强>
纯bash中的可扩展解决方案(更改n的值以更改第N行以外的当前行的cat):
<command that output something> | (n=3; i=0;
while [ $i -lt $n ]; do read line[$i]; i=$((i+1)); done;
while read line[$n]; do
echo "${line[0]},${line[$n]}";
i=0; while [ $i -lt $n ]; do line[$i]=${line[$((i+1))]}; i=$((i+1)); done;
done)
答案 3 :(得分:1)
开始编辑
比bellow更简单的解决方案,也可以很容易地修改到第N行behond,总是在sed中:
<command that output something> | sed -n -e '1h;2,3H;4,${H;g;s/\n.*\n/,/;p;g;s/^[^\n]*\n//;h}'
可以使用sed -n -f script
运行的解释版本:
# Do not put a \n in front of the hold space for the 1st line.
1h
# For all lines except the 1st, append to the hold space.
2,$H
# From the 1st line than need to be append to another line, 4 in this case, ...
4,${
# Copy the hold space in the patter space, replace all what is between \n by ',', and print.
g
s/\n.*\n/,/
p
# Remove the 1st line from the hold space.
g
s/^[^\n]*\n//
h}
结束修改
此外,无需文件的sed解决方案:
<command that output something> | sed -n -e 'H;g;s/^\n\(.*\)\n\(.*\n.*\n\)\(.*\)$/\1,\3\n\2\3/;t next;b;:next;P;s/^[^\n]*//;h'
作为所有神秘的sed解决方案,它值得一个解释,我以评论的sed脚本文件的形式提供,可以与sed -n -f script
一起运行:
# Append current line to the hold space and copy the hold space in the pattern space.
H
g
# Now, the hold and pattern space contain '\n<line1>\n<line2>...'.
# If we can match 4 lines in the pattern space, append 1st and 4th line at the beginning of the pattern space and remove the 1st line.
# If no substitution occurs, start next cycle, else print the concatenation, remove the concatenation from the pattern space, and copy the pattern space in the hold space for next cycle.
s/^\n\(.*\)\n\(.*\n.*\n\)\(.*\)$/\1,\3\n\2\3/
t next
b
:next
P
s/^[^\n]*//
h
答案 4 :(得分:1)
在bash中使用数组:
declare -a arr; arr=($(< line1to7))
for n in {0..3} ; do echo ${arr[n]}","${arr[$n+3]} ; done
line1,line4
line2,line5
line3,line6
line4,line7
答案 5 :(得分:0)
我可能会使用Perl,但你几乎肯定也可以使用Python。
use strict;
use warnings;
my(@lines);
while (<>)
{
chomp;
if (scalar @lines >= 4)
{
my $old = shift @lines;
print "$old,$_\n";
}
push @lines, $_;
}
给定一个非标准命令,range
生成第1行到第20行,以及xxx.pl
中的Perl脚本,这会产生:
$ range -f 'line%d' 1 20 | perl xxx.pl
line1,line5
line2,line6
line3,line7
line4,line8
line5,line9
line6,line10
line7,line11
line8,line12
line9,line13
line10,line14
line11,line15
line12,line16
line13,line17
line14,line18
line15,line19
line16,line20
$
如果那不是你想要的,你需要更清楚地解释你想要的东西。