在文件开头插入新行[重复]
Posted
技术标签:
【中文标题】在文件开头插入新行[重复]【英文标题】:Insert a new line at the beginning of a file [duplicate] 【发布时间】:2017-10-13 15:54:01 【问题描述】:有没有办法找到像*.js
这样的所有文件并在文件开头插入一些特定的行?寻找类似的东西:
find . -name '*.js' -exec sh -c '[insert this 'string'] "$0%.js"' \;
【问题讨论】:
【参考方案1】:这是一种在文件开头添加一行的方法:
sed -i '1s/^/line_to_be_added\n/' file
然后,您可以使用上面的代码和find
来实现您的最终目标:
find . -type f -name '*.js' -exec sed -i '1s/^/line_to_be_added\n/' \;
注意:此答案已经过测试,适用于 GNU
sed
。
编辑:上面的代码在.js
为空的文件上不能正常工作,因为上面的sed
命令在空文件上不能正常工作。解决方法是测试文件是否为空,如果是,则通过echo
添加所需的行,否则通过sed
添加所需的行。这一切都可以在(长)单行中完成,如下所示:
find . -type f -name '*.js' -exec bash -c 'if [ ! -s "" ]; then echo "line_to_be_added" >> ; else sed -i "1s/^/line_to_be_added\n/" ; fi' \;
编辑 2:正如用户 Sarkis Arutiunian 指出的那样,我们需要在表达式前添加 ''
和 \'$'
在 \n
前添加,以使其在 MacOS sed 中正常工作。这里是一个例子
sed -i '' '1s/^/line_to_be_added\'$'\n/' filename.js
编辑 3:这也有效,编辑者会知道如何语法高亮:
sed -i '' $'1s/^/line_to_be_added\\\n/' filename.js
【讨论】:
谢谢!但是还有一些事情,在 OSX 上,您需要在-i
之后添加 ''
,如下所示:sed -i '' '1s/^/line_to_be_added\n/' file
否则它将不起作用,而 \n
不起作用,它只是忽略 ` and inserting symbol
n `
@Sarkis Arutiunian 感谢您提供的信息。我没有安装OSX
,因此我也无法对此进行测试。我相信必须在sed
OSX
上使用\\\n
才能使newline
工作,对吧?你是如何让sed
newline
在OSX
上工作的?
不,这个\'$'\n/
所以完整的命令将是sed -i '' '1s/^/line_to_be_added\'$'\n/' file
@Sarkis Arutiunian 太好了,感谢您发布此内容,我学到了新东西,这也将对其他人有所帮助。
@JamilSaid:如果您将这些信息作为您的答案的一部分,它将对其他人有更大的帮助——人们往往会忽略 cmets,尤其是在冗长的交流中。还要注意sed
有一个专用函数 用于插入文本:i
(同样,a
用于附加 文本)。然而,便携使用仍然很棘手:sed '1i/line_to_be_added/' file
可以与 GNU sed
一起使用,但是 portable 命令(例如,也可以在 macOS 上使用)需要i
后跟 \<newline>
,插入字符串后跟另一个 <newline>
。【参考方案2】:
可移植性:使用 Sed 的保存空间
如果您想要一个可移植适用于 GNU 和 BSD sed 的解决方案,请使用以下内容将文本添加到第一行,然后将其余部分保持不变:
sed '1 x; s/^.*/foo/; G; ' example.txt
假设一个语料库:
bar
baz
这将打印:
foo bar baz
您可以将转换保存在脚本中,然后在确定一切后使用 find 或 xargs 和 sed -i
标志进行就地编辑正在按您预期的方式工作。
警告
使用 sed 有一个主要限制:如果文件为空,它就不会像您预期的那样工作。从您的原始问题来看,这似乎不太可能,但如果有这种可能,那么您需要使用 cat <(echo foo) example.txt | sponge example.txt
之类的东西来就地编辑文件,或者使用临时文件并在连接它们后移动它们。
注意:海绵是非标准的。它可以在moreutils 包中找到。
【讨论】:
不需要神秘的x
和G
Sed 函数,因为有一个专门用于插入文本的函数:i
。是的,您需要 \
后跟 actual 换行符,以便在文本前后插入以供便携式使用,但这是一个很小的代价,并且在 bash
、ksh
、@ 987654334@,如果必须使用单行解决方案,您可以使用 ANSI C 引用的字符串。例如,sed $'1i\\\ninsert me\n'
可以。
谈到奥术(在元注释上,因为这似乎是你的习惯):当“输入”或“输入”等更常见的词时,请不要使用“语料库”这个词文本”就可以了。除了不必要的神秘之外,使用“语料库”的方式是inconsistent with common usage。
@mklement0 如果它们如此神秘,那么为什么这些选项仍包含在sed
的最新发行版中?为什么它们不被弃用?您的解决方案不允许在搜索或替换字符串中直接使用 shell 变量,但您 可以 使用提供的答案(并将操作字符串更改为双引号)。因此,如果您想根据您的建议这样做,则需要支付另一个“代价”,如果您这样做,您可能会得到一个实际上比最初提供的解决方案更“神秘”的解决方案。
既然你已经从评论中删除了尖酸刻薄的内容,@Jon,让我认真地回答:神秘的品质与弃用无关;奥术的核心含义是“被少数人理解”,这与两个因素有关,第一个因素通常会引发第二个因素:概念复杂性阻碍理解,以及在实践中不经常使用。我认为这两个因素都适用于此,但您确实对字符串插值有一点看法,ANSI C 引用不支持。但是,您可以简单地使用 多行 "..."
字符串。
我看到你使用的仍然没有编辑你的 Wile E. Coyote。因此,如果我们在函数代码中使用为了可读性而缩进的多行字符串,我们必须做出进一步的牺牲,以保持新行的缩进以提高可读性。关于原始解决方案的适用性,您的结论是这些 sed
函数要么没有在实践中使用(我怀疑你有全面的证据),要么它太概念上复杂而无法理解。我真的不认为任何因素都适用,而且你对别人的建议看起来很冒昧。以上是关于在文件开头插入新行[重复]的主要内容,如果未能解决你的问题,请参考以下文章