I have some files in a directory:
a.csv b.csv c.csv
I wanted to write a bash script to add a filename at the end of each line of its file, like:
a.csv
line1 ,a
line2, a
line, a
b.csv
line1, b
line2, b
line3, b
How can I do this?
I have some files in a directory:
a.csv b.csv c.csv
I wanted to write a bash script to add a filename at the end of each line of its file, like:
a.csv
line1 ,a
line2, a
line, a
b.csv
line1, b
line2, b
line3, b
How can I do this?
With only GNU awk
assuming your files are a few and will not reach the ARG_MAX
limit:
gawk '{f=FILENAME; sub(/\.[^.]+$/, "", f); gsub(/\n/, "_NL_", f)}{{printf "%s, %s\n", $0, f}}' *.csv
Or in a shell loop for large number of files:
for f in *.csv; do
gawk '{f=FILENAME; sub(/\.[^.]+$/, "", f); gsub(/\n/, "_NL_", f)}{{printf "%s, %s\n", $0, f}}' "$f"
done
Notice: for gawk
to edit the files(instead of only printing to terminal), you need to set the -i inplace
flag like so:
gawk -i inplace '{f=FILENAME; sub(/\.[^.]+$/, "", f); gsub(/\n/, "_NL_", f)}{{printf "%s, %s\n", $0, f}}' *.csv
If, however, you insist on a pure bash
script ... Then, you can use this:
#!/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
Notice: This will only output to terminal for a dry-run ... To make it edit the files instead, you need to change simulation="on"
to simulation="off"
With awk
(assuming sanely named files):
for f in *.csv; do
awk '$++NF=o' OFS=', ' o=${f%.*} $f > $f_new
done