我的目录中有许多文本文件,我想删除目录中每个文件的最后一行。
我该怎么做?
答案1
如果您有 GNU,您可以使用这个漂亮的 oneliner sed
。
sed -i '$ d' ./*
它将删除当前目录中每个非隐藏文件的最后一行。-i
GNU 的switchsed
意思是原地操作,'$ d'
命令sed
删除最后一行($
意思是最后一行,d
意思是删除)。
答案2
如果目录包含常规文件以外的内容或文件名中包含空格/换行符的文件,其他答案都会出现问题。不管怎样,这里有一些有效的东西:
find "$dir" -type f -exec sed -i '$d' '{}' '+'
find "$dir" -type f
: 查找目录下的文件$dir
-type f
哪些是常规文件;-exec
对找到的每个文件执行命令sed -i
:就地编辑文件;'$d'
: 删除 (d
) 最后 ($
) 行。'+'
:告诉 find 继续添加参数sed
(比单独为每个文件运行命令更有效,感谢@zwol)。
如果您不想进入子目录,则可以将参数添加-maxdepth 1
到find
.
答案3
使用 GNUsed -i '$d'
意味着读取整个文件并制作一个没有最后一行的副本,而直接截断文件会更有效(至少对于大文件而言)。
使用 GNU truncate
,您可以执行以下操作:
for file in ./*; do
[ -f "$file" ] &&
length=$(tail -n 1 "$file" | wc -c) &&
[ "$length" -gt 0 ] &&
truncate -s "-$length" "$file"
done
如果文件相对较小,则效率可能会较低,因为它会为每个文件运行多个命令。
请注意,对于在最后一个换行符(最后一行之后)之后包含额外字节的文件,或者换句话说,如果它们具有非分隔的最后一个线,然后根据tail
实现,tail -n 1
将仅返回那些额外的字节(如 GNU tail
),或最后(正确分隔的)行和那些额外的字节。
答案4
更便携的方法:
for f in ./*
do
test -f "$f" && ed -s "$f" <<\IN
d
w
q
IN
done
我认为这不需要任何解释...除了在这种情况下可能与默认情况下选择最后一行d
相同。 这不会递归搜索,也不会处理隐藏文件(又名点文件)。 如果您也想编辑这些内容,请参阅$d
ed
如何将 * 与目录中的隐藏文件相匹配