For Loop : how to limit the activity for just 1st occurance where there are multiple matches in the loop

StackOverflow https://stackoverflow.com/questions/21928151

Pergunta

I am trying to execute a command that needs to run just ONCE for each distinct match of a SID in a file and there are many files out there in a the directory that share a SID.That is SID to (# files )is one is to many

delta_12012010_part01.dat
delta_12012010_part02.dat
delta_12012010_part03.dat
delta_12022010_part01.dat
delta_12022010_part02.dat
delta_12022010_part03.dat

The 12012010 part is the SID. There are 2 SID's in the above listing each w/ 3 parts . I am running something like this

find $targetdir -name "$sting*" | <some commands> | while read filename
do
SID=${filename:x:y}
if [ "$SID" -ge "$R1" ] && [ "$SID" -le "$R2" ]; then
function1  paras
function2  paras 
fi
done 

Function1 needs to executed just ONCE for an instance of SID . and function2 needs to run as expected for ALL instances of filename . I wonder how I can do that

on 2nd thoughts : One way to do it is to write the SID to a temp file and then sort | uniq the file and run the function 1 through a separate, do while loop

find $targetdir -name "$sting*" | <some commands> | while read filename
do
SID=${filename:x:y}
echo "$SID" >> tmpfile 
if [ "$SID" -ge "$R1" ] && [ "$SID" -le "$R2" ]; then
# function1  paras
function2  paras 
fi
done 

cat tmpfile | sort | uniq | while read filename 
do
function1 para
done 

But that above needs 2 loops and also the function1 works separately and not concomitantly with function2.So the question, I guess, is any way to do this elegantly .

@Tim Verhoeven. Thx So re-written this would be

tmp=
find <command ...> while read filename 
do
SID=${filename:x:y}


# this makes  it dependent on function outcome .
# Which I dont mind actually that why I wrote it as below 
 { [ "$tmp" -ne "$SID" ] ; }  &&  { function1 paras && tmp=$SID  || echo "some error msg"  ; }


# this makes  it independent on function outcome .
# Which will make it  the equivalent of the if statement 
 { [ "$tmp" -ne "$SID" ] ; }  &&  { function1 paras   || echo "some error msg"  ; }
 tmp=$SID


function2 paras
 done 

Just check if the above looks good.

Foi útil?

Solução

Sort your files by name and then use a temporary variable to compare sids against, only run function 1 when sid is different from temporary variable.

osid=0
find . -name "delta*" -exec ls -1 {} \+| while read f; do
    sid=$(echo $f | sed s'/.*delta_\([0-9]*\).*/\1/')
    echo "Running func 2 $f $sid $osid"
    if [[ "$osid" -ne "$sid" ]]; then
        echo "Running func 1 $f $sid $osid"
    fi
    osid=$sid
done
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top