0

I'm trying to write a bash queue which will be able to load command sets from a file and then execute each over a set of files. The prepared file should serve as a template for execution in manual bash queues

prepared file sed.sh: (I have also comments in the file but i don't know how to add them here)

sed -e 's,something_complex_long,something_even_longer,'
sed -e 's,other_complex_long_thing,something_so_much_longer,'
sed -e 's,another_long_stuff,something_hell_long,'

and there is directory with set of quite huge files with generic names such as aa ab ac etc. (sliced down even bigger file using split)

So I tried:

sedie=\`grep -v -e '^#' ../../sed.sh\`
for i in *
do
  for b in $sedie
  do
    cat $i | $b > ${i}.new
    mv ${i}.new $i
  done
done

Which of course totally failed, since the second for breaks up statements in $sedie by spaces.

Then I tried to go along using IFS as I have found somewhere but still not much progress. Then I thought I should load the commands in some kind of array to help differentiate what I want ... maybe change sed.sh like arr=("sed " "sed " "sed ") and then source sed.sh and then for b in ${arr[*]}?

Anybody please know how to deal with this in an elegant way (e.g., reusable) manually ?

My IFS try was rather cumbersome and didn't work anyway... $b became a single statement including the spaces and all and there were no such command

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
sedie=\`grep -v -e '^#' ../../sed.sh\`
for i in *
do
  for b in $sedie
  do
    echo cat $i \| $($b) \> ${i}.new
    echo mv ${i}.new $i
  done
done
IFS=$SAVEIFS

which was not elegant at all.

UPDATE #1

Using this Q: extract file contents into array using bash scripting and this one: How to execute command stored in a variable?, now I'm able to ..

$ cat > myfile 
aaaaaaaa
aaaaaaa
aaaaaa
aaaa
aa
aaaa

$ cat sed.sh 
sed -e 's/a/b/g'
sed -e 's/b/c/g'
sed -e 's/c/f/g'

$ declare -a pole
$ readarray pole < sed.sh
$ for ((i=0;i<${#pole[@]};i++));do \
    eval ${pole[i]} xfile > xfile.b; mv xfile.b xfile; done; 

$ cat xfile
ffffffff
fffffff
ffffff
ffff
ff
ffff

Which is almost what I needed. So my question is basically two:

how to read file into array?

and

how to execute command in variable?

  • 1
    Rather than invoking sed repeatedly in a loop, why not just put the sed expressions in a file and apply them to each file using sed -f script-file <yourfiles>? – steeldriver Jul 17 '15 at 1:19
  • @sudo - please do not use the answer section for follow up information - use the edit button below your Q to refine it as new information becomes available. – slm Jul 17 '15 at 7:30
0

This may not be exactly what you are after but since it looks like you are using sed the you could create a file sed.cmd with just the sed commands you want to execute.

s,something_complex_long,something_even_longer,
s,other_complex_long_thing,something_so_much_longer,
s,another_long_stuff,something_hell_long,

I used the following in my test sed.cmd

s/dog/cat

Then create a script that reads those commands into an array and call sed passing in those commands

array=()

# Read the file in parameter and fill the array named "array"
getArray() {
    i=0
    while read line # Read a line
    do
        array[i]=$line # Put it into the array
        i=$(($i + 1))
    done < $1
}

getArray "sed.cmd"

for cmd in "${array[@]}"
do
    ls -1 | while read line 
do 
    cat $line | sed -e $cmd > ${line}.new
    mv ${line}.new $line
done
done

You will probably want to change the ls command to order the files but the above seems to meet your requirements.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.