-1

I am using the below script to read the values of the 3rd column of the CSV file. However, I am getting a Syntax error.

tr -d '\r' < p_test.csv > fixed_p_test.csv
while IFS="," read -r rec1 rec2
do
  echo "Displaying Record-$rec1"
  echo "Price: $rec2"

done < <(cut -d "," -f1,3 fixed_p_test.csv | tail -n +2)

While running the above script I am getting the below error:

pScanFinal.sh: line 9: syntax error near unexpected token `<'

pScanFinal.sh: line 9: `done < <(cut -d "," -f1,3 fixed_p_test.csv | tail -n +2)'

My p_test.csv look like:

A B C D E
192.158 True 12 HT Open
254.658 False 58 SM Closed

How can I resolve this error?

oguz ismail
  • 1
  • 16
  • 47
  • 69
Pawan
  • 563
  • 1
  • 6
  • 19
  • is your shebang `#!/bin/bash`? – Fravadona Apr 28 '22 at 17:53
  • How are you running the script? Are you sure you're using bash to invoke it? I don't get a syntax error on my system, and `shellcheck` is happy with it. – Keith Thompson Apr 28 '22 at 17:53
  • You aren't actually running the script with `bash`. – chepner Apr 28 '22 at 17:53
  • @KeithThompson I am running it using "sh pScanFinal.sh" – Pawan Apr 28 '22 at 18:11
  • you should update the question to show the expected output – markp-fuso Apr 28 '22 at 18:17
  • since it's closed, here's my one-liner solution without needing to pre-clean \r or use [ while read ] : mawk 'NF= 2 * ( _ * ($2 = $(sub("\r?$", _ )))) ^ (FNR == !+( $!_ = "Displaying Record " $3 ))' FS=',' OFS='\nPrice: ' p_test.csv ………….Displaying Record 12 ………….Price: 192.158 ………….Displaying Record 58 ………….Price: 254.658..… This works cuz it's trying to evaluate NF = 2 * 0 ^ (FNR==1), 1st row evaluates NF = 2 * 0^1 -> NF = 2* 0 -> NF=0, so nothing gets printed , otherwise it's NF = 2 * 0^0 -> NF= 2*1 -> NF=2. It needs to be "2" because I'm using half of the text as OFS. – RARE Kpop Manifesto Apr 28 '22 at 19:02
  • The usual way to run a Bash script is to (a) make sure the first line is `#!/bin/bash`; (b) make sure the script file is executable (`chmod +x ...`) and (c) invoke the script itself: `pScanFinal.sh`, not `sh pScanFinal.sh`. (And if your script depends on Bash features, naming it with `.sh` is misleading. See https://stackoverflow.com/a/27824204/827263 – Keith Thompson Apr 28 '22 at 19:05
  • < continuing my own comment … > another variation of that idea but shifting items around would be mawk 'NF *= ( ( $( ($2 = $(sub(/[\r]?$/, _ ) ) )^ _ ) = "Displaying Record "$(NF=3) )^!--NF ) < FNR' FS=',' OFS='\nPrice: ' – RARE Kpop Manifesto Apr 28 '22 at 19:24

2 Answers2

1

You don't actually need cut, tail, or process substitution here, which means you can make your script POSIX compliant to match how you are running it.

{
    read  # Skip the first line
    while IFS=, read -r rec1 _ rec2 _; do
        ...
    done
} < fixed_p_test.csv
chepner
  • 497,756
  • 71
  • 530
  • 681
  • { read while IFS=, read -r rec1 _ rec2 _; done echo "Price: $rec2" done } < fixed_p_test.csv Error occurred: pScanFinal.sh: line 7: syntax error near unexpected token `done' pScanFinal.sh: line 7: ` while IFS="," read -r rec1 _ rec2 _; done' – Pawan Apr 28 '22 at 18:09
  • Typo; I used `done` instead of `do` to start the loop. – chepner Apr 28 '22 at 18:13
0

As jq is tagged (yet I don't know why), here's how to do it with jq.

Input and output should be read (-R) and written (-r) as raw text. Then split (/) each line by comma (,), and select column [2] (0-based).

jq -Rr '(./",")[2]' file.csv
12
58

Demo


Not asked/tagged, but imho awk would be more appropriate:

awk -F, '{print $3}' file.csv
pmf
  • 24,478
  • 2
  • 22
  • 31
  • Thanks, @pmf for the awk alternative, Could you also please help me with storing the result in an array? – Pawan Apr 28 '22 at 18:25
  • @Pawan An array in `jq`, in `awk` or in `bash`? – pmf Apr 28 '22 at 18:25
  • I am going with the awk alternative to fetch the column values. – Pawan Apr 28 '22 at 18:28
  • To read into a `bash` array, wrap it in parens and assign it to a `bash` variable: `a=($(awk -F, '{print $3}' file.csv))`. Then `echo ${a[0]}` will output `12`, and `echo ${a[1]}` will output `58`. – pmf Apr 28 '22 at 18:33
  • 1
    To read into an `awk` array, use a length counter as index, and assign the value to the next index position: `{a[++len]=$3}`. Then `{print a[1]}` will output 12, and `{print a[2]}` will output `58`. – pmf Apr 28 '22 at 18:46
  • awk command is to extract the data. How can we insert the array into csv for each index? – Pawan Apr 28 '22 at 19:55
  • @Pawan I'm not sure what "insert the array into csv for each index" means. Do you really need an (`awk` or `bash`) array after all? What is your ultimate goal? If it is a CSV file, just generate it from `jq` using `@csv`. – pmf Apr 29 '22 at 01:53
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244339/discussion-between-pawan-and-pmf). – Pawan Apr 29 '22 at 14:06