Shell 将一个文件的内容复制到另一个文件中相对于文件末尾的位置
StackExchange新手,请原谅我的错误 我有一个输入文件,需要在最后一个字符之前复制到另一个文件中 inputfile.txt:Shell 将一个文件的内容复制到另一个文件中相对于文件末尾的位置,shell,awk,sed,posix,sh,Shell,Awk,Sed,Posix,Sh,StackExchange新手,请原谅我的错误 我有一个输入文件,需要在最后一个字符之前复制到另一个文件中 inputfile.txt: input { "inputstuff" } filetowriteto.txt: Stuff { foo { "foostuff" } bar { "barstuff" } } Stuff { foo {
input {
"inputstuff"
}
filetowriteto.txt:
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
}
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
运行脚本后,生成的文件现在应该是:
filetowriteto.txt:
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
}
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
基本上,脚本会复制输入
行集,并将它们粘贴到filetowriteto.txt中最后一个右括号之前
脚本不能依赖行数,因为filetowriteto.txt
没有可预测的foo或bar行数,我不知道如何使用sed或awk来完成此操作。尝试:
$ awk 'FNR==NR{ if (NR>1) print last; last=$0; next} {print " " $0} END{print last}' filetowriteto.txt inputfile.txt
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
要就地更改文件,请执行以下操作:
awk 'FNR==NR{ if (NR>1) print last; last=$0; next} {print " " $0} END{print last}' filetowriteto.txt inputfile.txt >tmp && mv tmp filetowriteto.txt
工作原理
FNR==NR{if(NR>1)最后一次打印;最后一次=$0;下一次}
读取第一个文件时,(a)如果我们不在第一行,则打印last
的值,(b)将当前行的文本指定给last
,以及(c)跳过其余命令并跳到下一行
这使用了一个常见的awk技巧。只有在读取第一个文件时,条件FNR==NR
才为真。这是因为,在awk中,NR是我们迄今为止读取的行数,而FNR是我们迄今为止从当前文件读取的行数。因此,FNR==NR
只有在我们从第一个文件读取时才是真的
print”“$0
在读取第二个文件时,打印每一行的前导空格
END{print last}
打印完第二个文件后,打印第一个文件的最后一行
给定:
$ cat /tmp/f1.txt
input {
"inputstuff"
}
$ cat /tmp/f2.txt
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
}
您可以使用来实现这一点:
$ ( sed '$d' f2.txt ; cat f1.txt ; tail -n1 f2.txt )
或(此版本不创建子shell)
它是如何工作的
sed'$d'f2.txt
打印f2.txt的最后一行以外的所有内容
cat f1.txt
在该点打印f1.txt
tail-n1 f2.txt
现在打印f2的最后一行
如果要缩进f1.txt,请使用sed而不是cat。您还可以使用sed打印最后一行:
$ { sed '$d' /tmp/f2.txt ; sed 's/^/ /' /tmp/f1.txt ; sed -n '$p' /tmp/f2.txt; }
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
然后,如果愿意,可以使用
重定向将分组的输出重定向到文件
$ cat tst.awk
NR==FNR {
rec = (NR>1 ? rec ORS : "") $0
next
}
FNR>1 {
print prev
if ( sub(/[^[:space:]].*/,"",prev) ) {
indent = prev
}
}
{ prev=$0 }
END {
gsub(ORS,ORS indent,rec)
print indent rec ORS prev
}
$ awk -f tst.awk inputfile.txt filetowriteto.txt
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
上面使用要修改的文件最后一行之前的最后一个非空行的缩进,为插入的新文件设置缩进