Sandeep Rana
Sandeep Rana

Reputation: 3441

bash Shell: lost first element data partially

Using bash shell: I am trying to read a file line by line. and every line contains two meaning full file names delimited by "``"

file:1 image_config.txt

bbbbb.mp4``thumb/hashdata.gif
bbbbb.mp4``thumb/hashdata2.gif

Shell Script

#!/bin/bash
filename="image_config.txt"

while IFS='' read -r line || [[ -n "$line" ]]; do

IFS='``' read -r -a array <<< "$line"
if [ "$line" = "" ]; then
echo lineempty
else

file=${array[0]}
hash=${array[2]}

    echo $file$hash;
    output=$(ffmpeg -v warning -ss 2 -t 0.8 -i $file -vf scale=200:-1 -gifflags +transdiff -y $hash);
    echo $output;
#    echo ${array[0]}${array[1]}${array[2]}
fi;

done < "$filename"

first time executed successfully but when loop executes second time. variable file lost bbbbb from bbbbb.mp4 and following output comes out

Output :

user@domain [~/public_html/Videos]$ sh imager.sh 
bbbbb.mp4thumb/hashdata.gif

.mp4thumb/hashdata2.gif
.mp4: No such file or directory

lineempty

Upvotes: 2

Views: 69

Answers (2)

J. Chomel
J. Chomel

Reputation: 8395

Here is how you could do differently, avoiding a read in the read:

#!/bin/bash
filename="image_config.txt"

while IFS='' read -r line || [[ -n "$line" ]]; do
  if [ "$line" = "" ]; then
    echo lineempty
  else

  file=$( echo ${line} | awk -F \` ' { print $1 } ' )
  hash=$( echo ${line} | awk -F \` ' { print $3 } ' )

      echo $file$hash;
      output=$(ffmpeg -v warning -ss 2 -t 0.8 -i $file -vf scale=200:-1 -gifflags +transdiff -y $hash);
      echo $output;
  fi;

done < "$filename"

Upvotes: 1

Rany Albeg Wein
Rany Albeg Wein

Reputation: 3474

Please check out Bash FAQ 89 - I'm using a loop which runs once per line of input but it only seems to run once; everything after the first line is ignored? which seems to be helpful in your case.


Aside:

There is no point in using the same character twice in IFS.

IFS=\`

Is enough.

Check out this:

var='abc``def'
IFS=\`\` read -ra arr <<< "$var"
printf '<%s>\n' "${arr[@]}"

Output:

<abc>
<>
<def>

As you can see, arr[0] is abc, arr[1] is empty and arr[2] is def, and not arr[0] is abc and arr[1] is def as one might expect.

Taken from the IFS wiki of Greycat and Lhunath Bash Guide :

The IFS variable is used in shells (Bourne, POSIX, ksh, bash) as the input field separator (or internal field separator). Essentially, it is a string of special characters which are to be treated as delimiters between words/fields when splitting a line of input.

Upvotes: 2

Related Questions