LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-10-2012, 01:41 AM   #1
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Rep: Reputation: 282Reputation: 282Reputation: 282
shell; number of elements in array


I'm busy with a file rename script. A typical filename that needs renaming consists of two parts (both variable length) separated by '@S' (e.g. 'wim@S1.mpg'); the separator must be changed to '@' so the resulting filename is 'wim@1.mpg'. Filenames that don't contain '@S' don't need to be renamed.

I parse the filename into an array (using tr) which works. I however don't seem to be able to determine the number of elements of the array. It either gives me the length of the element (when I use dash as the shell) or it gives the length 1 for any parsed filename if I use bash. I've tried to change ${#arr[*]} to ${#arr[@]} but that does not help. The rest of the code works (as far as I currently can see); it indeed populates the variable newname with the correct filename (so the array contains multiple elements if the original filename contains '@S'.

Code:
#!/bin/bash
if [ $# -ne 1 ]; then
  echo "Usage: $0 pathtoassets"
  exit
fi

for f in $1/*.mpg
do
  #parse filename
  arr=$(echo $f | tr "@S" "\n");
  # get number of elements in array
  len=${#arr[*]}
  echo elements:  $len

  # create new filename
  newname=""
  for x in $arr
  do
    newname=$newname@$x
  done

  #rename filename
  echo "moving $f to $newname"
#  mv $f $newname

done
A possible workaround is to compare the filenames to the new filename before moving but I like to know why I can't determine the number of elements in the array.

Thanks in advance

PS running Ubuntu 10.04 for development and it needs to be moved to a Fedora system but I will take that hurdle later.

PPS
There is still a bug in the newname creation but I will solve that myself.

Last edited by Wim Sturkenboom; 07-10-2012 at 02:16 AM.
 
Old 07-10-2012, 02:44 AM   #2
bigearsbilly
Senior Member
 
Registered: Mar 2004
Location: england
Distribution: Mint, Armbian, NetBSD, Puppy, Raspbian
Posts: 3,515

Rep: Reputation: 239Reputation: 239Reputation: 239
Code:
for f in *@S1*;do echo mv $f ${f/@S/@} ;done
my motto:
If you are using shell arrays, it's time to think again.

Last edited by bigearsbilly; 07-10-2012 at 02:45 AM.
 
Old 07-10-2012, 03:20 AM   #3
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Original Poster
Rep: Reputation: 282Reputation: 282Reputation: 282
Thanks; I don't script too often so lack experience on what is available and I live from internet examples

I encountered some issues with the use of 'tr' (it uses each of the characters in the first argument as a separator) so was looking at another solution and indeed dropped the array completely.

Code:
#!/bin/bash
if [ $# -ne 1 ]; then
  echo "Usage: $0 pathtoassets"
  exit
fi

shopt -s nullglob
for f in $1/*.mpg
do
  # generate new filename
  newname=${f//"@S"/"@"}

  #rename filename
  if [ "$f" == "$newname" ]; then
    echo "skipping $f"
  else
    if [ -f $newname ]; then
      echo "skipping $f; will not overwrite existing file $newname"
      continue
    fi
    echo "moving $f to $newname"
    mv "$f" "$newname"
  fi
done
Leaves the question WHY I can't determine the length of the array?
 
Old 07-10-2012, 03:25 AM   #4
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,999

Rep: Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190
Firstly I agree with the above, but as to a solution to your question, you did not create an array, hence you are not getting the results you expect:
Code:
arr=$(echo $f | tr "@S" "\n")

arr=($(echo $f | tr "@S" "\n"))
First example (yours) assigns a the string output of the commands to 'arr', which by the way looks like:
Code:
wim

1.mpg
(Your tr replaces each character with a new line, which might also not be what you expected)

The second example uses () to let bash know that you are assigning an array. It will show an answer of only 2 elements but I caution you against your current solution.
 
Old 07-10-2012, 03:28 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,999

Rep: Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190
You may need to be careful with your changes, // and / as a replacement do different things.
 
Old 07-10-2012, 04:00 AM   #6
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Original Poster
Rep: Reputation: 282Reputation: 282Reputation: 282
Quote:
Originally Posted by grail View Post
Firstly I agree with the above, but as to a solution to your question, you did not create an array, hence you are not getting the results you expect:
...
...
Thanks, that explains it

Quote:
Originally Posted by grail View Post
You may need to be careful with your changes, // and / as a replacement do different things.
// replaces all '@S' while / only does the first one. If I'm incorrect, please correct me. Source: table B-5 at http://www.tldp.org/LDP/abs/html/refcards.html#AEN22587

I indeed want to replace every '@S' by '@'.

Thanks again, billy and grail
 
Old 07-10-2012, 09:57 AM   #7
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,999

Rep: Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190
No you are correct ... just didn't want you to get caught with another not predicted result
 
Old 07-10-2012, 11:39 PM   #8
Wim Sturkenboom
Senior Member
 
Registered: Jan 2005
Location: Roodepoort, South Africa
Distribution: Ubuntu 12.04, Antix19.3
Posts: 3,794

Original Poster
Rep: Reputation: 282Reputation: 282Reputation: 282
The single slash gave me the unpredicted result Thanks
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Perl - Regex with Array Elements BarataPT Programming 6 03-14-2011 03:03 PM
How do I get the number of elements in a char*[] in c++? chinho Programming 7 01-28-2011 01:30 AM
awk: Using split to divide string to array. How do I find out the number of elements? vxc69 Programming 9 02-09-2008 12:49 PM
odd behaviour of array elements in c++ markhod Programming 4 03-14-2005 09:58 AM
perl - get number of elements in an array AM1SHFURN1TURE Programming 3 03-07-2005 03:59 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 08:24 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration