有没有一条Unix命令可以将一些字符串数据添加到文本文件的开头?
类似于:
prepend "to be prepended" text.txt
有没有一条Unix命令可以将一些字符串数据添加到文本文件的开头?
类似于:
prepend "to be prepended" text.txt
printf '%s\n%s\n' "to be prepended" "$(cat text.txt)" >text.txt
echo "to be prepended"$'\n'"$(cat text.txt)"
。 - jbo5112printf '%s\n%s\n' "要预置的内容" "$(cat text.txt)" >text.txt
可以避免echo -e
的更不幸的副作用。(这仍然不是特别好的做法——取决于在重定向之前执行命令替换的shell——但至少通过这种修复,在通常方式下行为的shell中,它不会在一般情况下进行不需要的修改)。 - Charles Duffysed -i.old '1s;^;to be prepended;' inFile
-i
写入原地更改,并在给定任何扩展名的情况下进行备份。 (在这种情况下,.old
)1s;^;要添加的内容;
将第一行的开头替换为给定的替换字符串。 1
表示作用于第一行,s
表示替换,;
是我们选择的 s
的分隔符(/
是常见选择,如 s///
,但可以使用任何字符),^
是匹配行开头的正则表达式如果您想在文件开头添加一个新行,您需要在替换字符串中添加 \n
,如下所示:
sed -i.old '1s;^;to be prepended\n;' inFile
\n
,具体取决于他们的需求。很棒的解决方法。 - LevoninFile
的路径中可以包含目录吗? - zakdances\n
。本应先阅读评论的。该死。 - chishaku;
时,本应该使用 /
。因为如果你在替换文本中使用了分隔符(例如,在文件路径前缀中),就不能再使用 /
作为分隔符。 - Mark McDonald我很惊讶没有人提到这个。
cat <(echo "before") text.txt > newfile.txt
这种方法可以说比被接受的答案更自然(将内容打印并输入到替换命令中是字典顺序上不直观的)。
...并且借用ryan上面说的,使用 sponge
你就不需要一个临时文件:
sudo apt-get install moreutils
<<(echo "to be prepended") < text.txt | sponge text.txt
编辑:看起来这在 Bourne Shell /bin/sh
中不起作用。
使用 Here-String - <<<
,你可以做到:
<<< "to be prepended" < text.txt | sponge text.txt
<<(echo "to be prepended") < text.txt
和 <<< "to be prepended" < text.txt
构造在bash中不起作用,它们需要zsh。 - Anders Kaseorg这是一种可能性:
(echo "to be prepended"; cat text.txt) > newfile.txt
你可能不容易避免使用中间文件。
其他选择(可能需要费力地进行shell转义):
sed -i '0,/^/s//to be prepended/' text.txt
cat <(echo "to be prepended") text.txt > newfile.txt
。想想看,我不确定我的回答是否相关,所以我发布了一个单独的答案。 - Sridhar Sarnobat( ... )
生成子shell 是不必要的:shell 可以完全通过重定向组命令 { ... }
的输出来处理。需要注意的是,shell 语法要求在 }
前加上终止分号或换行符,但在 )
前不需要。 - Alex Shpilkin注意:
这样做可能会产生意想不到的副作用,尤其是可能将符号链接替换为常规文件,最终得到的文件权限可能会有所不同,并且更改文件的创建时间。
sed -i
(例如Prince John Wesley的回答中所述)试图至少恢复原始权限,但其他限制也适用。
这里有一个简单的替代方法,使用临时文件(它避免了像shime的解决方案那样将整个输入文件读入内存的方式):
{ printf 'to be prepended'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt
使用 组命令 ({ ...; ...; }
) 比使用 子 shell ((...; ...)
) 稍微更有效率,就像0xC0000022L 的解决方案中所示。
优点包括:
很容易控制新文本是直接附加到第一行还是插入为 新行(只需将\n
添加到 printf
参数即可)。
与 sed
的解决方案不同,它适用于输入文件为空的情况(0
字节)。
如果意图是将一个或多个 完整的行 前置到现有内容中,则可以简化sed
解决方案 (假设输入文件非空):
sed
的 i
函数可以插入整行:
使用 GNU 的 sed
:
# Prepends 'to be prepended' *followed by a newline*, i.e. inserts a new line.
# To prepend multiple lines, use '\n' as part of the text.
# -i.old creates a backup of the input file with extension '.old'
sed -i.old '1 i\to be prepended' inFile
一种便携的变体,也可在 macOS / BSD 上使用的 sed
:
# Prepends 'to be prepended' *followed by a newline*
# To prepend multiple lines, escape the ends of intermediate
# lines with '\'
sed -i.old -e '1 i\
to be prepended' inFile
请注意,\
后面的字面换行符是必需的。
使用古老的 ed
POSIX 实用程序:
注意:
ed
无论如何都会首先将整个输入文件读入内存。要在直接在第一行之前添加内容(与 sed
类似,如果输入文件为空(0
字节),则此方法将不起作用):
ed -s text.txt <<EOF
1 s/^/to be prepended/
w
EOF
-s
抑制ed
的状态消息。<<EOF\n...\nEOF
)形式提供给ed
的,即通过标准输入(stdin)传递;默认情况下,在这些文档中执行字符串扩展(shell变量被插值化);引用开头的定界符可抑制此操作(例如:<<'EOF'
)。1
将第一行设为当前行。s
函数在当前行上执行基于正则表达式的字符串替换,就像sed
一样;您可以在替换文本中包含literal新行,但它们必须进行\
转义。w
将结果写回到输入文件(测试时,将w
替换为,p
只打印结果,而不修改输入文件)。要在一个或多个整行之前添加内容:
与sed
类似,i
函数会始终向要插入的文本添加一个结尾换行符。
ed -s text.txt <<EOF
0 i
line 1
line 2
.
w
EOF
0 i
立即将当前光标移动到文件开头的第0
行并开始插入模式(i
)。请注意,行号从1
开始计数。.
作为终止符。echo -e "to be prepended \n another line" | cat - text.txt
需要重写文件,因为不能将内容传送回原输入文件,所以需要一个临时文件。
echo "to be prepended" | cat - text.txt > text.txt.tmp
mv text.txt.tmp text.txt
text.txt
的开头,而是在标准输出上显示它。如果适用于原帖作者,该输出可以被输入到另一个文件中。 - Levon$ echo RewriteBase / | cat - web/.htaccess > web/.htaccess
cat:web/.htaccess:输入文件是输出文件
- geek-merlin#!/bin/bash
echo -n "$1" > /tmp/tmpfile.$$
cat "$2" >> /tmp/tmpfile.$$
mv /tmp/tmpfile.$$ "$2"
至少要有类似的东西...
$$
是不够安全的(会受到谷歌符号链接攻击);但是相对于静态文件名,它肯定更好。 - tripleeemktemp
。 - mewa解决方法:
printf '%s\n%s' 'text to prepend' "$(cat file.txt)" > file.txt
!@#$%^&*()丑陋的文本\n\t\n
,它将正常工作:printf '%s\n%s' '!@#$%^&*()ugly text\n\t\n' "$(cat file.txt)" > file.txt
"$(cat file.txt)"
。所有解决方法都比较复杂。如果您想保留file.txt文件末尾的换行符,请参阅此链接:https://dev59.com/zWs05IYBdhLWcg3wIedj#22607352。file.txt
的内容大于可以适合传递给printf
的参数列表,则会出现问题。 - Jonathan Leffler另一种使用 sed
的方法:
sed -i.old '1 {i to be prepended
}' inFile
sed -i.old '1 {i\
to be prepended\
multiline
}' inFile
sed -i '1ito be prepended' inFile
呢?难道这只适用于 GNU sed 吗? - user unknownsed
中,i
命令后面跟着一个反斜杠和一个换行符,每个输入行除了最后一行都以反斜杠结尾。GNU sed
允许类似你所问的简写方式,但只有GNU sed
才能这样做。 - Jonathan Leffler
<<(echo "to be prepended") < text.txt | sponge text.txt
。该命令将文本文件中的内容与准备添加的文本组合起来,并将结果写回到原始文件中,同时确保安全地处理输出。 - Sridhar Sarnobat