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

时间:2011-10-18 19:22:05

标签: shell sed find

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

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来做。

5 个答案:

答案 0 :(得分:5)

未经测试,请尝试使用xargs

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

答案 1 :(得分:5)

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

当我回答这个问题时,你的“没有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 -r 's#(.\/)(.*)# MAGIC #ge'
  • 这样的sed行
  • 请记住,在上面一行中,我们有两个组\1: "./"\2 "a.txt"(filename)
  • 因为我们在sed行末尾有e,所以 MAGIC 部分会是 作为shell命令执行。(需要GNU sed)
  • MAGIC cat &\|sed "s:^:file \2 :g cat&amp;只是输出文件 内容,并管道到另一个sed。做替换(s:..:..:g
  • 最后,MAGIC的执行结果将是替换 外面的sed。

关键是Gnu sed的'e'。

答案 2 :(得分:1)

为什么不直接用ls代替第一行中的find

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

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

答案 3 :(得分:1)

这个对我来说很好用,而且比肯特的答案更容易使用
注意:不会为该

插入完整的路径名
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' {}

答案 4 :(得分:0)

怎么样:

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