Shell脚本-读取文件的两行,并读取另一个文件的一行
喂,我有两个文件 文件1包含:Shell脚本-读取文件的两行,并读取另一个文件的一行,shell,Shell,喂,我有两个文件 文件1包含: line1 line2 line3 line4 line5 line6 line7 line8 line9 line10 anotherline1 anotherline2 anotherline3 文件2包含: line1 line2 line3 line4 line5 line6 line7 line8 line9 line10 anotherline1 anotherline2 anotherline3 我想做一个while循环,以便将其输出到文件3
line1
line2
line3
line4
line5
line6
line7
line8
line9
line10
anotherline1
anotherline2
anotherline3
文件2包含:
line1
line2
line3
line4
line5
line6
line7
line8
line9
line10
anotherline1
anotherline2
anotherline3
我想做一个while循环,以便将其输出到文件3:
line1
line2
anotherline1
line3
line4
anotherline2
line5
line6
anotherline3
line7
line8
anotherline1
line9
line10
anotherline2
我在这里寻找答案,但我不知道怎么做。
我必须说我对shell脚本非常在行
另外:“while循环”应该一直持续到文件1的末尾。不管File2有多长,实际上,在我个人的场景中,File2总是比File1短。输出应为:File1Line1、File1Line2、File2Line1、File1Line3、File1Line4、File2Line2。。。。等
有什么帮助吗
注意:如果之前已经回答过,那么mods请关闭此问题。在谷歌搜索了几个小时后,我就是找不到任何答案
编辑:添加了何时结束循环的说明。我不知道有什么方便的方法可以在纯shell脚本中完成特定的操作。您最好只编写一个python/perl/etc.脚本。类似于这个awk脚本的东西可以工作,但有点混乱:
awk '{
print; getline; print;
if (!getline < "file2") {
close("file2");
getline < "file2"
};
print
}' file1
awk'{
打印;获取行;打印;
如果(!getline<“file2”){
关闭(“文件2”);
getline<“文件2”
};
打印
}'文件1
打印;getline;print
将打印文件1中的下一行,获取该行之后的行,然后打印它。如果(!getline<“file2”)
尝试从file2读取下一行,如果失败,则关闭它,隐式重新打开它,并从file2读取第一行。最后的打印
将打印文件2中的那一行(下一行或第一行)。在本机shell中很容易完成--不需要像awk
这样的外部工具。打开两个绑定到不同文件的文件描述符,并对这两个描述符进行迭代
while :; do
read -r line1 <&3 && printf '%s\n' "$line1" || break
read -r line2 <&3 && printf '%s\n' "$line2" || break
read -r line3 <&4 || { exec 4<file2 && read -r line3 <&4; }
printf '%s\n' "$line3"
done 3<file1 4<file2 1>file3
while:;做
read-r line1此awk应能工作:
awk 'FNR==NR{a[++i]=$0; next} FNR%2{p=$0; curr=(FNR==1 || curr==i) ? 1 : curr+1; next}
{print p ORS $0 ORS a[curr]}' file2 file1
line1
line2
anotherline1
line3
line4
anotherline2
line5
line6
anotherline3
line7
line8
anotherline1
line9
line10
anotherline2
编辑:甚至更短的awk
(感谢):
如果我正确地解释了你的问题,你想
逐步执行file1
start to finish,然后
在每两行之后插入file2
中的“下一行”,每当内容用完时,将其旋转回file2
的顶部
如果这就是目标,那么可以通过多种方式使用awk实现,但是下面的shell代码片段可能就可以了
#!/usr/bin/env bash
mapfile -t file2 < file2
max=${#file2[@]}
while read line; do
((count++))
echo "$line"
if [[ $((count%2)) == 0 ]]; then
if [[ next -ge max ]]; then
next=0
fi
echo "${file2[next++]}"
fi
done < file1
#/usr/bin/env bash
mapfile-t file2
这样做的缺点是将所有file2
作为数组加载到内存中。如果因为文件太大而出现问题,您可以添加一些shell glop,以便在每次调用循环时查找特定的行,尽管这会非常慢。更好的是,更具体地定义你的问题,或者考虑替代的工具!p>
另外请注意,mapfile
命令是一个bash-4-ism,因此如果您使用的是较旧的Linux或OSX(仍然随bash 3提供),则需要一个不同的解决方案。。。或者是对bash的升级。解释一下你的一行程序是如何工作的将是非常有教育意义的!:-)因此,如果我在末尾添加>file3,输出将是我想要的?我现在就试试…(说清楚点,我唯一反对的是,这不能在纯壳中实现的说法——请看我的答案作为反例——否则就很好了)。@ghoti补充了一个解释。现在读起来容易多了。我喜欢这个答案的简单逻辑。向上投票:)顺便说一句——如果两个输入文件中的行数不匹配(file2中的一行对应file1中的每两行),您希望如何执行此操作?“while循环”应该一直持续到file1的末尾。不管File2有多长,实际上,在我个人的场景中,File2总是比File1短。输出应为:File1Line1、File1Line2、File2Line1、File1Line3、File1Line4、File2Line2。。。。你可以考虑把它编辑到你的问题中去;它显著地改变了正确答案的构成。在我们到达文件2的末尾后,是否应该为原本应该从中产生的行保留空格,还是应该将其忽略?添加到问题中。谢谢,我的错^_^乌西斯(第一个例子)正是我想要的。虽然如果到达文件2的末尾,while也会结束,我希望它一直运行,直到文件1的所有行都被读取。继续运行,做什么?在文件2中的内容本来应该是空的地方添加空行?只需从文件1添加更多行?第一个示例修改为忽略文件2上的EOF。@user3246010,啊。必须重新阅读一下这个问题,才能得出您希望从头开始使用file2的结论。如果你能用英语而不是仅仅用例子来说明,你会很感激的。你从哪里得到这种“回头看”的行为?我看不到任何规范(除了程序不能在那一点退出)。可以考虑在这里指定BASH 4。x的需要,使用<代码> MaPrase< /Cord>。(顺便说一句,有很多简单的方法可以在文件2结束时重新打开它;你可以阅读这个!!!这正是我想要的。如果我把我的问题弄得太复杂了,我真的很抱歉。但这肯定解决了它。谢谢!!@CharlesDuffy,关于bash 4的要点很好-我修改了这个答案。关于“简单的方法”,我认为多个文件句柄是比数组更高级的脚本功能,因此对于不熟悉其使用的人来说可能不会“更容易”。谢谢你的建议。这是一个golfed版本,有趣的是awk'FNR==NR{a[n++]=$0;next}1;!(FNR%2){print a[I++%n]}file2 file1
Wow这更好(在答复中添加)。