【问题标题】:Bash- Find file and insert text in beginning of empty and non-empty files?Bash-在空文件和非空文件的开头查找文件并插入文本?
【发布时间】:2020-05-03 08:59:43
【问题描述】:

我对 bash 命令很陌生。有人可以帮我解决这个问题吗?

我必须在当前目录中找到所有 .txt 文件,并在这些文件的开头添加一个文本。我在下面写了命令-

find . -name *.txt | xargs sed -i '1iadd text here'

此命令适用于所有非空文件。但它不适用于那些为空的文件。我发现这是因为 sed 命令未能在空文件中找到第一行,因此该命令未执行。 还有其他方法可以为空文件添加文本吗?

【问题讨论】:

  • 可以使用临时文件吗?

标签: linux bash unix xargs


【解决方案1】:

ed Unix 文本编辑器可以做到这一点。

for f in *.txt; do
  printf '%s\n' '0a' 'insert some text here' . w | ed -s "$f"
done
find . -type f -name '*.txt' -exec sh -c 'for f; do printf "%s\n" 0a "insert some text here" . w | ed -s "$f"; done' {} +
find . -type f -name '*.txt' -print0 | while IFS= read -rd '' file; do ed -s "$file" <<< $'0a\ninsert some text here\n.\nw\nq'; done

可以使用ed 脚本来完成。

cat script.ed

输出

0a
insert some text here
.
w
q

现在是for loop

for f in *.txt; do ed -s "$f" < ./script.ed; done

使用查找。

find . -type f -name '*.txt' -exec sh -c 'ed -s "$1" < ./script.ed' sh {} \;

两者的结合。

find . -type f -name '*.txt' -exec sh -c 'for f; do ed -s "$f" < ./script.ed; done' _ {} +
  • 在您的示例中,第一行是1,动作是i(表示插入),ed 也是如此,这意味着它也不适用于 ed,因为文件为空并且不包含任何行,但这里我使用的地址为0,操作是a,这意味着append,有效。

  • 1234563脚本。
  • 请注意,ed 会就地编辑文件,因此请务必备份您正在编辑的内容以防万一...

【讨论】:

  • 很高兴看到其他人在答案中使用ed。我并不孤单!
  • 是的。它有一些用处,你似乎也在你的一些帖子中使用它。
【解决方案2】:

很难改进短单行。有时最好准备一段典型的、自我解释的代码,不太紧凑,有一些假设(这里:临时文件),但在 100% 的情况下工作,例如:

for file in `ls *.txt`; do awk 'BEGIN {print "add text here"}{print$0}' $file > tmp.tmp | mv tmp.tmp $file; done

或者更确切地说(已编辑):

for file in ./*.txt; do awk 'BEGIN {print "add text here"}{print$0}' "$file" > tmp.tmp | mv tmp.tmp "$file"; done

然后尝试混合解决方案。

编辑:

如果您必须使用findxargssed,并且sed 无法正常处理空文件,您可以在文件中追加一个空行,插入文本,然后删除附加行:

find . -type f -name '*.txt' | xargs -I "%" sh -c 'echo "" >> "%"; sed -i -e "1iadd text here" -e "$ d" "%"'

【讨论】:

【解决方案3】:

在原地添加 ex:

ex -s '+0s/^/add text here/' '+:wq' my_file

从标准输入到标准输出:

ex -s '+0s/^/add text here/' '+%print' '+:wq' /dev/stdin

请注意,这仅适用于单个文件,与 sed 不同。

所以对于你的情况:

$ ls
empty  not_empty
$ stat --format '%n: %s' *
empty: 0
not_empty: 6
$ cat empty 
$ cat not_empty 
a
b
c
$ find . -type f | xargs -I '{}' ex -s '+0s/^/add text here/' '+:wq' '{}'
$ cat empty 
add text here
$ cat not_empty 
add text herea
b
c

请注意,-I 用于强制 xargs 对每个文件执行一次 ex,而不是尝试聚合参数。

为了完整起见,从标准输入到标准输出的过滤器示例:

$ printf "%s\n" hello world | ex -s '+0s/^/add text here/' '+%print' '+:wq' /dev/stdin
add text herehello
world
$ cat /dev/null | ex -s '+0s/^/add text here/' '+%print' '+:wq' /dev/stdin
add text here

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-16
    • 1970-01-01
    • 2022-01-04
    • 2012-03-20
    • 2012-03-05
    • 2018-04-08
    • 2017-10-18
    相关资源
    最近更新 更多