我有一个包含2800个.txt文件的文件夹,我需要删除每个文件的第一行。除了以.txt结尾的事实之外,文件的名称都是不同的。
是否可以在保持相同文件名的同时(而不是将输出(没有第一行的文件)发送到另一个文件)...
答案 0 :(得分:4)
类似这样的伎俩
sed -i '1d' *.txt
其中-i是就地编辑
编辑:adition
请尝试这个
time sed -i '1d' *.txt
并与其他解决方案进行比较(之前只添加时间)[尝试使用一些备份文件]
答案 1 :(得分:2)
你可以做一个bash脚本。像这样:
#!/bin/bash
for filename in *;
do
tail -n +2 "${filename}"
done
从命令行运行它:$ <script_file.sh>
带上一粒盐。我实际上并没有在* nix机器上运行。请参阅删除文件第一行的here for a variety of ways。另请注意,如果性能对您很重要,tail
应该比sed
快得多。
答案 2 :(得分:0)
对于少量文件,我写的是
for f in *.txt; do sed 1d "$f" >tmpfile; mv tmpfile "$f"; done
但是,对于足够多的文件,这将无效,因为shell会将*.txt
扩展为太长的参数列表。
在这种情况下(听起来像你的情况),更好的方法是
ls | grep '.txt$' | while read f; do sed 1d "$f" >tmpfile; mv tmpfile "$f"; done
然而,你应该知道原则上存在问题(正如@EdMorton在对这个答案的早期版本的评论中所强调的那样)。一个是如果你不幸有一个名字以.txt
结尾的目录(如果你真的觉得有必要,你可以用test -f
来处理)会有麻烦。另一个是read
如果其中一个文件名中有一些奇怪的字符(例如\n
,比方说,或者一种或其他类型的引号),则可能会出现问题。您可以通过摆弄IFS
来处理此类事情(请参阅注释),但最好快速浏览一下您正在处理的文件,并首先修复这些错误的文件名。
你不应该做的是ls *.txt | ...
,因为如果文件的数量足够长,for f in *.txt; do ...
将无效,那么ls *.txt
也将无效。
你可以做更精细的事情。
find . -type f -name \*.txt | while read f; do ...
专门选择以.txt
结尾的文件,但我总是找到file
选项不整齐的选项,并且感觉ls
+ grep
在这里更整洁。
另一种可能性是
find . -type f -name \*.txt -exec sed -i 1d '{}' \;
这非常强大,但是像大多数非平凡的file
命令一样,它最终看起来像一团糟,你必须记住find
的非显而易见的语法。除非sed
支持无争论-i
选项(POSIX sed
没有-i
,否则将无效OS X和其他BSD上的sed
实际上需要指定扩展名。此外,此方法仅限于单个命令,因此在您需要对文件执行更多操作的情况下不起作用。