使用 find 和 sed 将文件名添加到文件开头

发布于 2024-12-10 18:30:34 字数 690 浏览 0 评论 0原文

使用以下内容,我将文件名添加到每行的前面,并将输出发送到单个文件。

ls | while read file; do sed -e "s/^/$file/g" $file > out; done

我想执行相同的 sed 替换,但使用 findexecxargs 命令 -

find . -type f -exec sed "s/^/{}/g" {} > out +

但我得到一个错误 -

find:-exec ... + 仅支持一个 {} 实例

输入文件如下 -

fileA.txt

A1
A2

fileB.txt

B1
B2

所需输出

fileA.txt A1
fileA.txt A2
fileB.txt B1
fileB.txt B2

我知道如何使用 awk 执行此操作,但我想这样做它与 sed、find 和 exec 或 xargs 一起使用。

using the following I add the file name to the front of each line and send the output to a single file.

ls | while read file; do sed -e "s/^/$file/g" $file > out; done

I want to perform the same sed replacement but using a find and exec or xargs command -

find . -type f -exec sed "s/^/{}/g" {} > out +

but I get an error -

find: Only one instance of {} is supported with -exec ... +

Input files are like this -

fileA.txt

A1
A2

fileB.txt

B1
B2

desired output

fileA.txt A1
fileA.txt A2
fileB.txt B1
fileB.txt B2

I know how to do this with awk, but I'd like to do it with sed, find and exec or xargs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

素罗衫 2024-12-17 18:30:34
 find . -type f |xargs awk '$0=FILENAME$0' > out

当我回答这个问题时,你的“no awk”行还没有出现。无论如何,看看下面我更新的答案:

根据评论更新

所以你想使用 find、exec/xargs 和 sed 来完成它。我的脚本需要 GNU Sed,我希望你有它。

先看一行:(> out 被省略了,你可以将它添加到行尾。)

find . -type f | xargs -i echo {}|sed -r 's#(.\/)(.*)#cat &\|sed  "s:^:file \2 :g"#ge'

现在我们来测试一下,如下:

kent$  head *.txt
==> a.txt <==
A1
A2

==> b.txt <==
B1
B2

kent$  find . -type f | xargs -i echo {}|sed -r 's#(.\/)(.*)#cat &\|sed  "s:^:file \2 :g"#ge'
file b.txt B1
file b.txt B2
file a.txt A1
file a.txt A2

结果是你期望的吗?

简短解释

  • find ....|xargs -i echo {} 没什么可解释的,只需打印
    每行文件名(以 "./" 开头)
  • ,然后将文件名传递给 sed 行,如 sed -r 's#(.\/)(.*)# MAGIC
    #ge'
  • 请记住,在上面的行中,我们有两个组 \1: "./"
    \2 "a.txt"(filename)
  • 因为我们在 sed 行末尾有 e,所以 MAGIC 部分将是
    作为 shell 命令执行。(需要 GNU sed)
  • MAGIC: cat &\|sed "s:^:file \2 :g cat & 只是输出文件
    内容,并通过管道传输到另一个 sed。 最后进行replace(s:..:..:g)
  • ,MAGIC的执行结果将是Replacement
    外部 sed。

关键是 Gnu sed 的“e”。

 find . -type f |xargs awk '$0=FILENAME$0' > out

as I answered this, your "no awk" line not yet there. anyway, take a look my updated answer below:

updated based on comment

so you want to use find, exec/xargs, and sed to do it. My script needs GNU Sed, i hope you have it.

see the one liner first: (well, > out is omitted. You could add it to the end of the line. )

find . -type f | xargs -i echo {}|sed -r 's#(.\/)(.*)#cat &\|sed  "s:^:file \2 :g"#ge'

now let's take a test, see below:

kent$  head *.txt
==> a.txt <==
A1
A2

==> b.txt <==
B1
B2

kent$  find . -type f | xargs -i echo {}|sed -r 's#(.\/)(.*)#cat &\|sed  "s:^:file \2 :g"#ge'
file b.txt B1
file b.txt B2
file a.txt A1
file a.txt A2

is the result your expectation?

Short explanation

  • find ....|xargs -i echo {} nothing to explain, just print the
    filename per line (with leading "./")
  • then pass the filename to a sed line like sed -r 's#(.\/)(.*)# MAGIC
    #ge'
  • remember that in the above line, we have two groups \1: "./" and
    \2 "a.txt"(filename)
  • since we have e at the end of sed line, the MAGIC part would be
    executed as shell command.(GNU sed needed)
  • MAGIC: cat &\|sed "s:^:file \2 :g cat & is just output the file
    content, and pipe to another sed. do the replace (s:..:..:g)
  • finally, the execution result of MAGIC would be the Replacement of
    the outer sed.

the key is the 'e' of Gnu sed.

内心荒芜 2024-12-17 18:30:34

未经测试,尝试使用 xargs

find . -type f | xargs -I FILE sed "s/^/FILE/g" FILE > out

untested, try using xargs

find . -type f | xargs -I FILE sed "s/^/FILE/g" FILE > out
凡间太子 2024-12-17 18:30:34

为什么不简单地用这样的 find 替换第一行中的 ls 呢?

find . -type f | while read file; do sed -e "s|^|$file|" $file > out; done

您只能将 s 的分隔符从 / 替换为文件名中未包含的其他内容。我选择了 | 作为示例。

Why don't you simply replace the ls in your first line with the find like this?

find . -type f | while read file; do sed -e "s|^|$file|" $file > out; done

You must only exchange the delimiter for s from / to something else not contained in your filenames. I have chosen | as an example.

要走干脆点 2024-12-17 18:30:34

这个对我来说效果很好,而且比肯特的答案更容易使用

注意:比为该路径插入完整路径名

find . -type f | xargs -r -t -i sed -r 's|^|'{}' |g' {}

使用此路径来仅保留裸文件名部分

find . -type f | xargs -r -t -i sed -r -e 's|^|'{}' |g' -e 's|^.+/||g' {}

,然后如果您对标准输出结果感到满意,您可以将 -i 开关添加到 sed 命令以覆盖文件

find . -type f | xargs -r -t -i sed -i -r -e 's|^|'{}' |g' -e 's|^.+/||g' {}

this one works fine for me and it is simpler to use than Kent's answer

NOTE: than the full pathname is inserted for that one

find . -type f | xargs -r -t -i sed -r 's|^|'{}' |g' {}

use this one instead to keep only the bare filename part

find . -type f | xargs -r -t -i sed -r -e 's|^|'{}' |g' -e 's|^.+/||g' {}

then if your are happy with stdout results you might add -i switch to the sed command to overwrite the files

find . -type f | xargs -r -t -i sed -i -r -e 's|^|'{}' |g' -e 's|^.+/||g' {}
千と千尋 2024-12-17 18:30:34

怎么样:

find . -type f | xargs -i echo FILE/{} > out

How about:

find . -type f | xargs -i echo FILE/{} > out
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文