清空多个 .csv 日志文件但保留标题

清空多个 .csv 日志文件但保留标题

我在顶级目录的 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-placeor-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 {} +

查看相关如何仅提取数据中的标题名称而不列出数据本身

相关内容