我在目录中有一些文件:
a.csv b.csv c.csv
我想编写一个 bash 脚本,在文件的每一行末尾添加一个文件名,例如:
a.csv
line1 ,a
line2, a
line, a
b.csv
line1, b
line2, b
line3, b
我怎样才能做到这一点?
答案1
仅使用 GNUawk
假设您的文件很少并且不会达到限制ARG_MAX
:
gawk '{f=FILENAME; sub(/\.[^.]+$/, "", f); gsub(/\n/, "_NL_", f)}{{printf "%s, %s\n", $0, f}}' *.csv
或者在针对大量文件的 shell 循环中:
for f in *.csv; do
gawk '{f=FILENAME; sub(/\.[^.]+$/, "", f); gsub(/\n/, "_NL_", f)}{{printf "%s, %s\n", $0, f}}' "$f"
done
注意:用于gawk
编辑文件(而不是仅仅打印到终端),您需要-i inplace
像这样设置标志:
gawk -i inplace '{f=FILENAME; sub(/\.[^.]+$/, "", f); gsub(/\n/, "_NL_", f)}{{printf "%s, %s\n", $0, f}}' *.csv
但是,如果您坚持使用纯bash
脚本...那么您可以使用它:
#!/bin/bash
simulation="on"
for f in *.csv; do
fn="${f//$'\n'/_NL_}"
fn="${fn%\.*}"
readarray -t tmp < "$f"
if [ "$simulation" == "off" ]; then
> "$f"
fi
for l in "${tmp[@]}"; do
if [ "$simulation" == "off" ]; then
printf "%s, %s\n" "$l" "$fn" >> "$f"
else
printf "%s, %s\n" "$l" "$fn"
fi
done
done
注意:这只会输出到终端进行试运行...要让它编辑文件,您需要更改simulation="on"
为simulation="off"
答案2
使用awk
(假设文件命名合理):
for f in *.csv; do
awk '$++NF=o' OFS=', ' o=${f%.*} $f > $f_new
done