我在顶级目录的 2 个子目录中有一些 .csv 日志文件,我想清空每个目录中的所有 .csv 日志文件,但保留标题,以便创建它们的应用程序可以重新填充它们。
我可以用来for file in /path/to/file/*; do > $file;done
清空文件,但标题也被删除了!
答案1
tmpfile=$( mktemp )
for pathname in /path/to/dir/*.csv; do
head -n 1 "$pathname" >"$tmpfile"
cat "$tmpfile >"$pathname"
done
rm "$tmpfile"
也就是说,使用head -n 1
临时文件提取标头(假设它只是第一行),然后截断原始文件并从临时文件插入标头。
如果所有文件中的标头完全相同:
tmpfile=$( mktemp )
set -- /path/to/dir/*.csv
head -n 1 "$1" >"$tmpfile"
for pathname do
cat "$tmpfile" >"$pathname"
done
rm "$tmpfile"
首先将位置参数设置为我们感兴趣的文件列表,然后从第一个文件中提取标题。该循环迭代位置参数(CSV 文件)并截断每个参数,插入标题。
在上面的两个示例中,假设模式/path/to/dir/*.csv
匹配全部受影响的文件。实际模式的现实世界示例可能是
/var/log/myprogram/dir1/*.csv /var/log/myprogram/dir2/*.csv
或者,如果您使用的是支持大括号扩展的 shell:
/var/log/myprogram/{dir1,dir2}/*.csv
答案2
如果您喜欢sed
提供--in-place
or-i
选项,则可以替换> "$file"
为sed -i 4q "$file"
,其中4
是您希望保留的标题行数。请注意,某些实现可能需要显式的空备份文件,即-i ''
.
如果文件数量不太大,那么您也许可以避免循环并直接传递文件列表,例如
sed -si 4q subdir1/*.csv subdir2/*.csv
(s
至少在 GNU sed 中可能是多余的,因为-i
暗示-s
)
或使用find
find path/to/dir -name '*.csv' -execdir sed -si 4q {} +