Bash-查找文件并在空文件和非空文件的开头插入文本?

问题描述 投票:0回答:2

我对bash命令很陌生。谁能帮我解决这个问题?

我需要找到当前目录下的所有.txt文件,并在这些文件的开头添加一段文字。我写了下面的命令

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

这个命令对所有非空文件都能正常工作。但是对于那些空的文件就不行了。我想这是因为 sed 命令在空文件中找不到第 1 行,因此命令无法执行。有没有其他的方法也能在空文件中添加文本?

linux bash unix xargs
2个回答
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,作品。

  • script.ed 是一个任意的名字,而 ././script.ed 指当前工作目录,如果您的 ed 脚本的绝对路径。ed 脚本。

  • 一句话的提醒。ed 在原地编辑文件,所以一定要备份你正在编辑的文件,以防万一......


1
投票

要改进简短的oneliners是很难的。有时候,准备一段典型的、自我解释的代码是很好的,不那么紧凑,有一些假设(这里:临时文件),但在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

然后尝试混合解决方案。

EDIT:

如果你必须使用 find, xargssedsed 对于空文件不能正常工作,您可以在文件中追加空行,插入文本,然后删除追加的行。

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

0
投票

在原地用 ex:

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

从stdin到stdout。

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 每个文件一次,而不是试图汇总参数。

为了完整起见,举一个从stdin到stdout的过滤器的例子。

$ 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
© www.soinside.com 2019 - 2024. All rights reserved.