开发者

shell script: nested while loop: not pickup the outer loop counter

开发者 https://www.devze.com 2023-04-12 10:50 出处:网络
I have a file that has millions of records.I will just make it simple with two sample records here.My goal is to add delimiters, such as a comma, to make the file has the same number of delimiters, so

I have a file that has millions of records. I will just make it simple with two sample records here. My goal is to add delimiters, such as a comma, to make the file has the same number of delimiters, so I can upload the file to a database.

The issue is that the nested while l开发者_高级运维oop simply added a fixed number of delimiters at the end of line. My goal is to add delimiters dynamically according to the number of delimiters the file already has. I changed the inner while loop to a if statement block, the same behavior happened as well. So I do not think a nested while loop is necessary.

Here is my sample text file:

1st,1,
2nd,2

Here is the script. First user input position is the text file, the second position is the number of delimiters I want.

#!/bin/bash

f="$1"
delim="$2"

while read line
do
cnt=`echo $line | tr -cd ',' | wc -c`
    while   [[ $cnt  -lt $delim ]];   
    do
            sed -i 's/$/,/' $f 
        cnt=`expr $cnt + 1`
    done
done  < $f

Here is my trace using bash -x:

bash -x csv.sh split_address_2.csv 3
+ f=split_address_2.csv
+ delim=3
+ read line
++ wc -c
++ tr -cd ,
++ echo 1st,1,
+ cnt=2
+ [[ 2 -lt 3 ]]
+ sed -i 's/$/,/' split_address_2.csv
++ expr 2 + 1
+ cnt=3
+ [[ 3 -lt 3 ]]
+ read line
++ wc -c
++ tr -cd ,
++ echo 2nd,2
+ cnt=1
+ [[ 1 -lt 3 ]]
+ sed -i 's/$/,/' split_address_2.csv
++ expr 1 + 1
+ cnt=2
+ [[ 2 -lt 3 ]]
+ sed -i 's/$/,/' split_address_2.csv
++ expr 2 + 1
+ cnt=3
+ [[ 3 -lt 3 ]]
+ read line

Here is the output of the text file. You can see the script simply added 3 commas at the end of each line.

1st,1,,,,
2nd,2,,,

Thanks so much for your kind response. Have a good day!


Why did you use sed -i here? By that command, you are doing a search and replace on your whole file there, on each line...

In your first line in your input file, there are already 2 commas, so your while-loop runs once, appending each line in your input file with an extra comma. On the second line, there's only one comma so your while-loop runs twice, appending each line in your your whole text with 2 extra comma. That's why there are 3 extra commas after each line when you have run your script.

I did some simple minor adjustment to your script. It works as your expected this time:

#!/bin/bash

f="$1"
delim="$2"

while read line
do
cnt=`echo $line | tr -cd ',' | wc -c`
    while   [[ $cnt  -lt $delim ]];   
    do
        line=`echo $line | sed 's/$/,/'`
        cnt=`expr $cnt + 1`
    done
    echo $line
done  < $f
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号