剪切一个文件的最后两行并重复附加到另一个文件中

剪切一个文件的最后两行并重复附加到另一个文件中

我尝试使用以下命令剪切文件的最后两行并将其附加到新文件中

tail -n -2 file1 >> file2 && head -n -2 file1 > tmp && mv tmp file1

每次手动执行上述代码时,最后两行文件1剪切并附加到文件2。但是,最好的方法是什么来自动执行此操作,直到文件1没有更多条目可以删减吗?

或者您是否有以完全不同的方式做到这一点?

答案1

在我看来,使用以下方法以相反的顺序阅读两行会更简单tac

tac file1 | while IFS= read -r a && IFS= read -r b; do printf '%s\n%s\n' "$b" "$a"; done >> file2

(当剩余行数少于 2 行时,此操作将终止file1- 谢谢u/artur meinild) 或者

tac file1 | sed -E '$!N;s/(.*)\n(.*)/\2\n\1/' >> file2

file1(即使行数是奇数,它也会持续到1 的末尾)。

或者使用 GNU 的类似方法parallel

tac file1 | parallel -N2 "printf '%s\n'" '{2}' '{1}' >> file2

  1. 如果你想使用 sed,但又像 while 循环版本那样忽略末尾的奇数行,则将其更改为sed -nE '$!N;s/(.*)\n(.*)/\2\n\1/p'仅在成功替换时打印

答案2

这是适合初学者的版本,使用带有 while 循环的脚本,易于阅读和理解:

#!/bin/bash

# Do this operation as long as file1 has content
while [[ -n $(cat file1) ]]
do
  # Put the 2 last lines of file1 in file2
  tail -n -2 file1 >> file2
  # Remove the last 2 lines of file1
  head -n -2 file1 > tmp && mv -f tmp file1
done

# If you want to remove the empty file1
# rm -f file1

即使file1行数为奇数,此解决方案仍然有效(那么 的第一行将file1是 的最后一行file2)。

答案3

好的,谢谢你们的建议。我尝试了一整天,在一些代码上遇到了困难,但最终我找到了解决方案。你们的想法是什么...我做了一个类似于 Arthur Meinild 提到的until循环。

until ! [ -s file_tmp ]; do
tail -n -2 file_tmp >> file.tmp && seq 2 | xargs -i sed -i -e '$d' file_tmp
done
rm file_tmp && cat file.tmp >> file
rm file.tmp

我曾用 head 代替 sed 来解决,但 head 的磁盘 io 负担更重。上面的 steeldriver 版本对我来说似乎也很有趣,但目前我将采用 sed 方式 :)

答案4

您可以使用三个命令来完成此操作。

(seq 10 提供了示例输入文件)

seq 10 | sed  -n '1~2p' | tac > odds
seq 10 | sed  -n '2~2p' | tac > evens
awk  '{getline line < "evens"; print $0; print line}'  odds

9
10
7
8
5
6
3
4
1
2

相关内容