将一个文件的内容复制到另一个文件中相对于文件末尾的位置
Copying the contents of a file into another file at a point relative to the end of the file
StackExchange 新手,如有错误请见谅。
我有一个输入文件需要复制到另一个文件中,在最后一个字符之前。
inputfile.txt:
input {
"inputstuff"
}
filetowriteto.txt:
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
}
在 运行 脚本之后,生成的文件现在应该是:
filetowriteto.txt:
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
基本上,脚本会复制 input
行集并将它们粘贴到 filetowriteto.txt
中最后一个右括号之前。
脚本不能依赖行数,因为 filetowriteto.txt
没有可预测数量的 foo 或 bar 行,而且我不知道如何使用 sed 或 awk 来执行此操作。
尝试:
$ awk 'FNR==NR{ if (NR>1) print last; last=[=10=]; next} {print " " [=10=]} END{print last}' filetowriteto.txt inputfile.txt
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
要就地更改文件:
awk 'FNR==NR{ if (NR>1) print last; last=[=11=]; next} {print " " [=11=]} END{print last}' filetowriteto.txt inputfile.txt >tmp && mv tmp filetowriteto.txt
工作原理
FNR==NR{ if (NR>1) print last; last=[=12=]; next}
在读取第一个文件时,(a)如果我们不在第一行,打印last
的值,(b)将当前行的文本分配给last
,和 (c) 跳过其余命令并跳转到 next
行。
这使用了常见的 awk 技巧。条件 FNR==NR
仅在我们读取第一个文件时为真。这是因为,在 awk 中,NR 是我们到目前为止已经读取的行数,而 FNR 是我们到目前为止从当前文件读取的行数。因此,FNR==NR
仅在我们从第一个文件读取时为真。
print " " [=18=]
在读取第二个文件时,打印每一行,并在前面加上一些白色 space。
END{print last}
我们打印完第二个文件后,打印第一个文件的最后一行。
鉴于:
$ cat /tmp/f1.txt
input {
"inputstuff"
}
$ cat /tmp/f2.txt
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
}
您可以使用 command grouping 来实现:
$ ( sed '$d' f2.txt ; cat f1.txt ; tail -n1 f2.txt )
或(此版本不创建子shell)
$ { sed '$d' f2.txt ; cat f1.txt ; tail -n1 f2.txt; }
它是如何工作的?
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 : "") [=10=]
next
}
FNR>1 {
print prev
if ( sub(/[^[:space:]].*/,"",prev) ) {
indent = prev
}
}
{ prev=[=10=] }
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"
}
}
上面使用要修改的文件的最后一行之前的最后一个非空行的缩进来设置它插入的新文件的缩进。
StackExchange 新手,如有错误请见谅。
我有一个输入文件需要复制到另一个文件中,在最后一个字符之前。
inputfile.txt:
input {
"inputstuff"
}
filetowriteto.txt:
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
}
在 运行 脚本之后,生成的文件现在应该是:
filetowriteto.txt:
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
基本上,脚本会复制 input
行集并将它们粘贴到 filetowriteto.txt
中最后一个右括号之前。
脚本不能依赖行数,因为 filetowriteto.txt
没有可预测数量的 foo 或 bar 行,而且我不知道如何使用 sed 或 awk 来执行此操作。
尝试:
$ awk 'FNR==NR{ if (NR>1) print last; last=[=10=]; next} {print " " [=10=]} END{print last}' filetowriteto.txt inputfile.txt
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
input {
"inputstuff"
}
}
要就地更改文件:
awk 'FNR==NR{ if (NR>1) print last; last=[=11=]; next} {print " " [=11=]} END{print last}' filetowriteto.txt inputfile.txt >tmp && mv tmp filetowriteto.txt
工作原理
FNR==NR{ if (NR>1) print last; last=[=12=]; next}
在读取第一个文件时,(a)如果我们不在第一行,打印
last
的值,(b)将当前行的文本分配给last
,和 (c) 跳过其余命令并跳转到next
行。这使用了常见的 awk 技巧。条件
FNR==NR
仅在我们读取第一个文件时为真。这是因为,在 awk 中,NR 是我们到目前为止已经读取的行数,而 FNR 是我们到目前为止从当前文件读取的行数。因此,FNR==NR
仅在我们从第一个文件读取时为真。print " " [=18=]
在读取第二个文件时,打印每一行,并在前面加上一些白色 space。
END{print last}
我们打印完第二个文件后,打印第一个文件的最后一行。
鉴于:
$ cat /tmp/f1.txt
input {
"inputstuff"
}
$ cat /tmp/f2.txt
Stuff {
foo {
"foostuff"
}
bar {
"barstuff"
}
}
您可以使用 command grouping 来实现:
$ ( sed '$d' f2.txt ; cat f1.txt ; tail -n1 f2.txt )
或(此版本不创建子shell)
$ { sed '$d' f2.txt ; cat f1.txt ; tail -n1 f2.txt; }
它是如何工作的?
sed '$d' f2.txt
打印除 f2.txt 最后一行以外的所有内容
cat f1.txt
在那个点打印 f1.txttail -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 : "") [=10=]
next
}
FNR>1 {
print prev
if ( sub(/[^[:space:]].*/,"",prev) ) {
indent = prev
}
}
{ prev=[=10=] }
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"
}
}
上面使用要修改的文件的最后一行之前的最后一个非空行的缩进来设置它插入的新文件的缩进。