是否有Unix命令将一些字符串数据添加到文本文件中?
就像是:
prepend "to be prepended" text.txt
<<(echo "to be prepended") < text.txt | sponge text.txt
是否有Unix命令将一些字符串数据添加到文本文件中?
就像是:
prepend "to be prepended" text.txt
<<(echo "to be prepended") < text.txt | sponge text.txt
Answers:
sed -i.old '1s;^;to be prepended;' inFile
-i
将更改写到位,如果有扩展名,则进行备份。(在这种情况下,.old
)1s;^;to be prepended;
;
用作命令定界符,用给定的替换字符串替换第一行的开头。\n
在前置之后插入;根据他们的需求。干净的解决方案。
inFile
路径中可以包含目录吗?
\n
。应该先阅读评论。该死的。
'1s;^;my-prepended-line\;\n;'
printf '%s\n%s\n' "to be prepended" "$(cat text.txt)" >text.txt
git config --get-regex $arg | sed -r 's/\t{3}/\\n/g';
并且在将\t
and 转换时将其弄乱了\n
。
echo "to be prepended"$'\n'"$(cat text.txt)"
我很惊讶没有人提到这一点。
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
建筑无法正常使用;他们需要zsh。
这是一种可能性:
(echo "to be prepended"; cat text.txt) > newfile.txt
您可能不会轻易绕过中间文件。
替代方案(如果要转义,可能会很麻烦):
sed -i '0,/^/s//to be prepended/' text.txt
cat <(echo "to be prepended") text.txt > newfile.txt
。想一想,我不确定我的与我有什么关系,所以我张贴了一个单独的答案。
这将形成输出。-表示标准输入,它是通过管道从回声中提供的。
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
按要求将文本添加到文件中,但是会在stdout上显示它。输出可以漏斗到不同的文件,如果该工程为OP
注意:
这样做可能会带来意想不到的副作用,特别是可能用常规文件替换符号链接,最终对文件具有不同的权限,并更改文件的创建(出生)日期。
sed -i
,就像约翰·卫斯理王子的回答一样,试图至少恢复原始权限,但其他限制同样适用。
这是一个使用临时文件的简单选择(避免像shime的解决方案那样将整个输入文件读入内存):
{ printf 'to be prepended'; cat text.txt; } > tmp.txt && mv tmp.txt text.txt
如使用0xC0000022L的解决方案一样,使用组命令({ ...; ...; }
)比使用子shell((...; ...)
)效率更高。
优点是:
很容易控制是将新文本直接添加到第一行还是将其插入为新行(只需附加\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
的状态消息。ed
作为多行here-document(<<EOF\n...\nEOF
)提供,即通过stdin;通过默认字符串膨胀是在这样的文档(shell变量被内插)来进行; 引用开头的定界符以取消该限制(例如<<'EOF'
)。1
使第一行成为当前行s
在当前行上执行基于正则表达式的字符串替换,如sed
;您可以在替换文本中包含文字换行符,但是它们必须是\
换行。w
将结果写回到输入文件(用于测试,代替w
与,p
仅打印的结果,而无需修改所述输入文件)。要在前面加上一个或多个整行:
与一样sed
,该i
函数始终将尾随换行符添加到要插入的文本中。
ed -s text.txt <<EOF
0 i
line 1
line 2
.
w
EOF
0 i
使0
(文件的开头)为当前行并开始插入模式(i
);请注意,否则行号1
基于。.
以其自己的行终止。在某些情况下,前置文本仅可从stdin获得。然后,此组合将起作用。
echo "to be prepended" | cat - text.txt | tee text.txt
如果要忽略tee
输出,请追加> /dev/null
。
tee
不会造成麻烦?我认为不是—这会使该解决方案对文件的健康造成危险。text.txt
cat
lenA=1000000; yes a | head -c $lenA > a.txt; lenB=10000; b=$(yes b | head -c $lenB); echo "$b" | cat - a.txt | tee a.txt > /dev/null
。如果lenA
为1000000(文件为1Mb)且lenB
为10000(文件为10Kb),则文件“ a.txt”将被20kb的“ b”字母覆盖。这完全被打破了。现在,如果使用1Mb a.txt和1Mb文本作为前缀,tee
则进入生成7Gb +文件的循环,我必须停止该命令。因此,很明显,对于大尺寸而言,结果是不可预测的。我不知道它是否应该在小尺寸上工作。
解:
printf '%s\n%s' 'text to prepend' "$(cat file.txt)" > file.txt
请注意,这对所有类型的输入都是安全的,因为没有扩展。例如,如果您想添加!@#$%^&*()ugly text\n\t\n
,它将可以正常工作:
printf '%s\n%s' '!@#$%^&*()ugly text\n\t\n' "$(cat file.txt)" > file.txt
需要考虑的最后一部分是命令替换期间文件末尾的空格删除"$(cat file.txt)"
。为此的所有变通办法都相对复杂。如果要在file.txt的末尾保留换行符,请参见:https : //stackoverflow.com/a/22607352/1091436
file.txt
大于可容纳到参数列表中的内容printf
。
如在Bash(在Ubuntu中)中所测试的,如果通过来启动测试文件;
echo "Original Line" > test_file.txt
您可以执行;
echo "$(echo "New Line"; cat test_file.txt)" > test_file.txt
或者,如果bash的版本对于$()而言过旧,则可以使用反引号;
echo "`echo "New Line"; cat test_file.txt`" > test_file.txt
并接收“ test_file.txt”的以下内容;
New Line
Original Line
没有中间文件,只有bash / echo。
另一个相当简单的解决方案是:
$ echo -e "string\n" $(cat file)
cat
在双引号中使用参数扩展,这是降低投票率的一个很好的理由。此代码将文件的内容拆分为多个单词,并将每个单词作为单独的参数传递给echo
。您失去了原始参数边界,失去了换行符/制表符/等,以及诸如\t
和的字符串\n
在原文与选项卡和换行,而不是因为他们是被保留取代。
如果您喜欢vi / vim,则可能更适合您。
printf '0i\n%s\n.\nwq\n' prepend-text | ed file
我建议定义一个函数,然后在需要的地方导入和使用它。
prepend_to_file() {
file=$1
text=$2
if ! [[ -f $file ]] then
touch $file
fi
echo "$text" | cat - $file > $file.new
mv -f $file.new $file
}
然后像这样使用它:
prepend_to_file test.txt "This is first"
prepend_to_file test.txt "This is second"
您的文件内容将为:
This is second
This is first
我将使用这种方法来实现变更日志更新程序。