2

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?

2 Answers2

3

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"

Raffa
  • 32,237
0

With awk (assuming sanely named files):

for f in *.csv; do
  awk '$++NF=o' OFS=', ' o=${f%.*} $f > $f_new
done
Thor
  • 3,578