我有十个文件:firstFile.txt
,...,tenthFile.txt
我想在文件的最后一行附加文件的名称。
即第一个的最后一行是firstFile
我想用一行代码执行此操作。
我是新手,所以不知道该尝试什么,我的猜测是类似的,echo * >> *.txt
但并不惊讶,它没有起作用
答案1
例如,可以通过使用循环来实现这一点for
,其语法如下:
for var in values; do things; done
此代码将列表中的第一个values
进入var
并执行things
然后将下一个值放入var
等等。
我们经常用它对一组文件做同样的事情,就像你想在这里做的那样。
您可以使用一些合适的表达式让 Bash 创建文件列表(我上面称之为值列表)。这里我建议您使用*File.txt
。这将由 shell 扩展为当前目录中以 结尾的所有文件的列表File.txt
。因此,代码的第一部分可能是
for f in *File.txt; do
您可以使用其他名称来代替f
来命名变量,例如file
。我建议使用小写的字母或单词(shell 中已经定义了其他使用大写单词的变量,我们不想覆盖它们)。在 Bash 中调用变量时,我们在其名称前加上$
。因此,您可以使用 或 来引用变量$f
,$file
shell 会将其扩展为该变量的当前值。为了防止结果进一步扩展,我们几乎总是使用双引号,因此当我调用变量时$f
,我会写而不是"$f"
。
要将一些文本发送到文件中,您可以使用简单的工具,例如printf
或echo
带有重定向。您已经表明您知道如何使用重定向将内容附加到文件中。这:替换stuff > file
file
和stuff
并附加stuff >> file
stuff
到file
。
我们应该非常小心地使用重定向,因为我们很容易覆盖重要文件 - 您甚至不会收到任何警告。因此,在运行如此强大的命令之前,您可能需要在另一个目录中备份文件,和/或进行试运行,只需检查将要操作的文件即可,如下所示:
for f in *File.txt; do echo "$f"; done
以上只是返回将要采取行动的文件列表。
现在让我们回过头来讨论如何向文件添加文本。由于我们的变量中已经有了文件的名称,我们可以使用它来生成文本。
您的代码如下所示echo
:
for f in *File.txt; do echo "$f" >> "$f"; done
对于firstFile.txt
,将运行echo firstFile.txt >> firstFile.txt
,依此类推,对于 匹配的所有其他文件也运行*File.txt
。
但是您提到您的文件以 结尾,.txt
并且您不希望它出现在附加的文本中。
为了避免这种情况,您可以执行一些字符串操作
for f in *File.txt; do echo "${f%.*}" >> "$f"; done
这将从中的字符串的${f%.*}
最后一个字符开始修剪字符,在本例中为。.
$f
.txt
您也可以使用printf
。它值得学习,因为它比更灵活echo
,而且据我所知,它也更可靠。
for f in *File.txt; do printf '%s\n' "${f%.*}" >> "$f"; done
'%s\n'
用于格式化 -%s
表示文本是一个字符串(例如,不是数字)并\n
在其后附加一个换行符(echo
自动附加一个换行符)。
答案2
您可以使用find
和来实现这一点bash
:
find <YOUR SEARCH PATH> -type f -exec bash -c 'filepath="{}"; filename=${filepath##*/}; echo ${filename%.*} >> $filepath' \;
在哪里
<YOUR SEARCH PATH>
- 包含文件的目录路径-type f
- 我们正在搜索文件,而不是目录等。-exec
- 执行 bash,其中字符串{}
被替换为当前正在处理的文件名filepath="{}"
- 创造文件路径正在处理的当前完整路径文件名变量filename=${filepath##*/}
- 创造文件名从完整路径中提取文件名的变量echo ${filename%.*} >> $filepath
- 删除最后一个点,扩展名为文件名变量并将名称附加到使用变量正在处理的文件文件路径
当然,bash 命令字符串可以缩短,只是试图更好地解释事情。