0

I have a list.csv with the following content:

"date";"Mr. Green Tree"
"date";"Mr. Red Apple"
"date";"Mr. Blue Car"

I use awk + sed to get the following output:

awk -F ";" '{print $2 }' list.csv | sed 's/"//g'

Output:

Mr Green Tree
Mr Red Apple
Mr Blue Car 

Now I want to use the same command in a for loop and add the string "Hello"

script.sh

get_name () {
    name=$(awk -F ";" '{print $2 }' list.csv | sed 's/"//g')
    for string in $name; do
        echo "Hello" $string
    done
}

get_name

Output when I execute script.sh:

Hello Mr
Hello Green
Hello Tree
Hello Mr
Hello Red
Hello Apple 
Hello Mr
Hello Blue
Hello Car 

Expected Output:

Hello Mr Green Tree
Hello Mr Red Apple
Hello Mr Blue Car
  • Do you have to use `for` AT ANY PRICE? – Daweo Jun 30 '22 at 11:42
  • @Daweo No, I dont think so. I have to generate a mail with this names later, e.g: Hello Mr Green Tree, here is your information (...). So I want to generate a .eml-File for each recipient (e.g. greentree@forerst.org) .. – citrusbytez Jun 30 '22 at 11:54
  • Then why not directly use `sed -e 's/"//g' -e 's/^/Hello /'` or `sed -e 's/"\(.*\)"/Hello \1/'` – Ashok Jun 30 '22 at 12:00
  • This question is closed as a duplicate of a question whose accepted answer is specific to what that user was trying to do (call other commands within the loop) but is a well known anti-pattern for people like the OP here who are not trying to do that, see [why-is-using-a-shell-loop-to-process-text-considered-bad-practice](https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice) – Ed Morton Jun 30 '22 at 12:36

3 Answers3

1

(Using your method...) Try:

awk -F ";" '{print $2 }' list.csv | sed 's/"//g' | while read -r line || [[ -n $line ]]; do 
    printf "Hello %s\n" "$line"
done 

If you know the input will be \n terminated:

awk -F ";" '{print $2 }' list.csv | sed 's/"//g' | while read -r line; do 
    printf "Hello %s\n" "$line"
done 

Bash loop from here


Or, if you looping over the file with Bash anyway, just do it all in Bash:

while IFS=';' read -r f1 f2; do 
    printf "Hello %s\n" "${f2:1:-1}" 
done <list.csv

Or (most recommended...) entirely in awk:

awk -F';' '{gsub(/"/,"",$2); print "Hello " $2}' list.csv
dawg
  • 98,345
  • 23
  • 131
  • 206
  • Only the awk script at the end will work portably, efficiently, and not corrupt the values being printed. You never need sed when you're using awk btw. `awk -F ";" '{print $2 }' list.csv | sed 's/"//g'` = `awk -F ";" '{gsub(/"/,"",$2); print $2 }' list.csv` – Ed Morton Jun 30 '22 at 12:24
  • So... ^1 for the awk answer at the end but not the 3 shell loops above it, I guess. – Ed Morton Jun 30 '22 at 12:37
0

An easy way of doing it without even a for loop:

cat list.csv | awk -F ";" '{print $2 }' | sed -e 's/\.//g' | sed 's/"//g' | awk '{print "Hello"" "$1,$2,$3}'

Output:

Hello Mr Green Tree
Hello Mr Red Apple
Hello Mr Blue Car
Apex
  • 1,055
  • 4
  • 22
  • Working too, less complex code. I only can mark one solution. Thanks! – citrusbytez Jun 30 '22 at 12:03
  • 2
    You never need sed when you're using awk and you never need `cat` to open a file. `cat list.csv | awk -F ";" '{print $2 }' | sed -e 's/\.//g' | sed 's/"//g' | awk '{print "Hello"" "$1,$2,$3}'` = `awk -F ";" '{gsub(/[."]/,"",$2); print "Hello", $2 }' list.csv` – Ed Morton Jun 30 '22 at 12:29
0

It works that way @dawg described, so I mark this as solution.

The suggestion from @Biffen is also working Looping through the content of a file in Bash

Code based on his answer:

get_name () {
    name=$(awk -F ";" '{print $2 }' list.csv | sed 's/"//g')
    while read p; do
        echo "Hello" $p
    done < $name
}

get_name
  • 1
    If you copy/paste your code into http://shellcheck.net it'll tell you about some of the problems with it. You should also read [why-is-using-a-shell-loop-to-process-text-considered-bad-practice](https://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice) for some more important issues and to learn why not to do this. You never need sed when you're using awk btw. – Ed Morton Jun 30 '22 at 12:22