Reputation: 37
Suppose I have a comma-separated file called 'list.txt' which contains the following:
1,fileA
2,fileB
I want to read these into a while loop in my csh script, so that I can manipulate the comma separated fields separately. I need to scale this up for any number of lines in the input text file as opposed to the 2 in this example.
#!/bin/csh
set j=1
while ($j <= 2)
set index = "`awk -F"," '{if (NR==$j) print $1}' list.txt`"
set file = "`awk -F"," '{if (NR==$j) print $2}' list.txt`"
echo $index
echo $file
@ j++
end
So I would expect the output of this to be
1
fileA
2
fileB
but in stead I get:
1,fileA
1,fileA
2,fileB
2,fileB
What am I missing here? If I run an equivalent awk command for any given line in the terminal outside of my csh script, it works as I expect it to.
awk -F"," '{if (NR==1) print $1}' list.txt
returns
1
I believe in the csh script the trouble is to do with the double inverted commas specifying the delimiter, which means something else in csh, but I can't figure out the solution.
Upvotes: 0
Views: 1710
Reputation: 203995
Here's how to do what you've told us about so far using any awk and a shell that supports arrays, e.g. bash:
$ awk -F, -v OFS='\n' '{$1=$1}1' file
1
fileA
2
fileB
$ IFS=$'\n' arr=( $(awk -F, -v OFS='\n' '{$1=$1}1' file) )
$ echo "${arr[0]}"
1
$ echo "${arr[1]}"
fileA
$ echo "${arr[2]}"
2
$ echo "${arr[3]}"
fileB
Now, if you tell us what it is you want to DO with the awk output we can provide guidance.
To be clear, the echos above are NOT part of any proposed solution, they are just to show an array was populated. Here's the same in a loop if you prefer (I added some surrounding <
>
chars in the echos just to make it clear what the echos are doing vs the awk):
$ cat tst.sh
IFS=$'\n' arr=( $(awk -F, -v OFS='\n' '{$1=$1}1' file) )
for i in "${arr[@]}"
do
echo "< $i >"
done
$ ./tst.sh
< 1 >
< fileA >
< 2 >
< fileB >
but it's not clear any of that is useful. This is much more likely to be what you want instead:
$ awk -F, -v OFS='\n' '{$1=$1}1' file | xargs -I {} -n1 echo "<" {} ">"
< 1 >
< fileA >
< 2 >
< fileB >
Again, until you show us what you want to do with the contents of your input file, we can't help you figure out how to implement a solution.
Given what you just stated in a comment about wanting to run a command named gausmooth
with args that include file names generated from your input file, here's one way to do that (remove the echo to execute the command instead of just printing it):
$ cat tst.sh
awk -F, '{print $2$1}' file |
xargs -I {} echo gausmooth in="/home/Documents/{}" out="/home/Documents/gs_{}"
$ ./tst.sh
gausmooth in=/home/Documents/fileA1 out=/home/Documents/gs_fileA1
gausmooth in=/home/Documents/fileB2 out=/home/Documents/gs_fileB2
Again - if that's not what you want, tell us the rest of the story.
Given your new, new requirements this may be what you want:
$ cat file
fileA1,fileA2
fileB1,fileB2
$
$ while IFS=, read -r in1 in2
do
echo gausmooth in1="/home/Documents/$in1" in2="/home/Documents/$in2" out="/home/Documents/gs_${in1%%[0-9]*}"
done < file
gausmooth in1=/home/Documents/fileA1 in2=/home/Documents/fileA2 out=/home/Documents/gs_fileA
gausmooth in1=/home/Documents/fileB1 in2=/home/Documents/fileB2 out=/home/Documents/gs_fileB
As I mentioned in a different comment the usual advice is to avoid shell loops in general but I use them sometimes for simplicity/clarity when I have control over the input and it is easily constrained so that's what I've done in this case. The assumptions are that none of your file names contain commas or newlines and that the name of the out
file can be created by stripping trailing digits off the first in
file.
Upvotes: 0
Reputation: 37
The solution in this case, was to use cut
in stead of awk
.
#!/bin/csh
foreach LINE ( `cat list.txt` )
set index = `echo "$LINE" | cut -d',' -f 1`
set file = `echo "$LINE" | cut -d',' -f 2`
echo $index
echo $file
end
which produces the desired output
1
fileA
2
fileB
and the strings are stored in variables for further use.
Upvotes: -1
Reputation: 16997
Try, if your interest is awk
[akshay@localhost tmp]$ cat infile
1,fileA
2,fileB
[akshay@localhost tmp]$ awk -F, '{$1=$1}1' OFS="\n" infile
1
fileA
2
fileB
[akshay@localhost tmp]$ awk 'gsub(/,/,"\n")+1' infile
1
fileA
2
fileB
Upvotes: 1
Reputation: 41460
Not sure what you goal is, but you can do:
tr ',' '\n' <file
1
fileA
2
fileB
Upvotes: 1