我有一个head
获取文件第一行的命令和一个sed
在文件第一行之前插入的命令。如何组合这些,以便我可以在另一个文件的第一行之前插入一个文件提取的第一行。
获取文件的第一行
head -n 1 file_to_get_first_line_from
在第一行之前插入
sed -i '1 i\insert_this_in_the_first_line' file_to_intert_into
答案1
如果您的file_to_insert_into
结尾不是换行符:
$ cat <<IN > file_to_insert_into
$(head -n1 file_to_get_first_line_from; cat file_to_insert_into)
IN
答案2
最便携的方法是使用POSIX 指定的功能ex
。
$ cat file1
Jack and Jill
Went up the hill
To fetch a pail of water.
$ cat file2
Nursery Rhymes:
Epic Poems:
Classic Literature:
$ printf '%s\n' '0r !head -n 1 file2' x | ex file1
$ cat file1
Nursery Rhymes:
Jack and Jill
Went up the hill
To fetch a pail of water.
printf
用于向 发送命令ex
。0
是提供给 ead 命令的地址r
;它指示ex
在“第 0 行之后”(即第 1 行之前)读入指定文本。!head -n 1 file2
意味着不是r
直接从文件中读取文本(a所有的文件),head
首先执行命令并读入其输出(在指定位置,第 0 行)。x
意思是保存并退出。
这完全符合 POSIX 标准且可移植。
如果您正在编写此脚本,那么最好检查一下您的假设:存在file2
且可读,并且file1
如果存在则可读且可写。
if [ -r file2 ] && [ -f file2 ] && { ! [ -e file1 ] || { [ -r file1 ] && [ -w file1 ];};}; then
printf '%s\n' '0r !head -n 1 file2' x | ex file1
fi
答案3
使用 Vim 和head
:
vim -Nesc '0r !head -n1 file_to_get_first_line_from' +wq file_to_insert_into
-Nes
启动不兼容、静默、ex 模式,当您想使用 Vim 编写任务脚本时,这很有用。-c '0r !<cmd>'
<cmd>
在第一行之前插入命令的输出。这里的命令当然是head
命令。+wq
保存并关闭文件。
答案4
更新:感谢 @Wildcard 指出 GNU Sed 的差异
北达科他州sed
在您的终端上尝试:
sed -i '' "1i\
$(head -n 1 file_to_get_first_line_from)" file_to_insert_into
- 这意味着开始输入
sed -i '' "1i\
,然后按 Enter 键继续命令的其余部分
解释
- 通过 Bash 命令替换帮助组合两个原始命令
$(
)
。$(
)
用它的输出替换里面的任何 bash 命令 - 我们将
'
文字引号更改为"
引号,以便允许 Bash 执行操作,同时仍然使用引号来sed
正确查看一个 sed 命令
GNUsed
或者如果你有 GNU sed:
sed -i "1i $(head -n 1 file_to_get_first_line_from)" file_to_insert_into
- 测试用
sed (GNU sed) 4.2.2
.要查看您的 sed 版本:sed --version
- GNU sed 可以省略
\
和 换行符。info sed
, 在下面sed Programs
,Common Commands
:
作为 GNU 扩展,如果在 'a' 和换行符之间存在除空白-'\' 序列之外的其他内容,则从 'a' 后的第一个非空白字符开始的该行文本将被视为TEXT 块的第一行。 (这可以简化单行添加脚本的编写。)此扩展还可以与“i”和“c”命令一起使用。
附加信息
- 或者,还有一个较短版本的 head 命令:
head -1
。但是info head
声称这是obsolete option syntax -[NUM]...
head 支持的,并建议“标准主机”使用该-n NUM
语法,因此我们可以在这里继续使用您的原始head -n 1
语法