0

I wrote a bash script that extract only the date from folder names and put what extract (dates) in a array to perform other operations. Local works fine, the problems appears when I want to do this remote on server.

I access the server via ssh , the part that extract the date from folder names work ok the main issue is when I want to populate the array with the dates.

Below are some code from my script:

#! bin/bash

ssh -t -t user@serveradress << 'EOT'

 # go in the path where to perform the extraction of dates
cd share/Pictures_G

 # create an array, perform the extraction of dates , populate the array with dates

declare -a all_dates

all_dates=($(ls | grep -o "[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}"))
len=${all_dates[@]}
echo "$len"
EOT

So the command ls | grep -o "[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}" work ok alone but when I use this in the way that I used in the script from above provide the next output:

all_dates=
len=
echo

nothing is passed to the array from my understanding.

Mihai
  • 29
  • 8
  • `ls` lists the files only not the dates. Also you get the length of the array via `len=${#all_dates[@]}`. Probably you want to use `find ` command which provides mechanism to find files by date. – stephanmg Nov 12 '19 at 09:25
  • Hello. The ' ls ' command is part from a more complex structure there. Also I dont want to use ' find ' because how is specifyed in the description I want to extract the date from the name this is the infromation relevant for my purpose. @stephanmg – Mihai Nov 12 '19 at 09:58
  • Do you need it to be stored in an array? – stephanmg Nov 12 '19 at 10:00
  • Possible duplicate of [How can I store the "find" command results as an array in Bash](https://stackoverflow.com/questions/23356779/how-can-i-store-the-find-command-results-as-an-array-in-bash) – stephanmg Nov 12 '19 at 10:02
  • Your parameter expansions and command substitutions are all done in the local shell instead of being passed to the remote shell. You need to quote the first `EOT` to disable expansions. Other folks are arguing irrelevant problems. – 4ae1e1 Nov 12 '19 at 11:44
  • @stephanmg Look at the output what I described. When I do < echo "$len" > I'' m expect to see the array, but < echo > it shows nothing at the output. – Mihai Nov 12 '19 at 11:55
  • @Mihai: See the duplicate I posted above, which also addresses your problem. – stephanmg Nov 12 '19 at 11:59
  • 1
    @stephanmg I'm gonna look. Thank you! – Mihai Nov 12 '19 at 13:15
  • @4ae1e1 . Using quotation marks introduces some problems, the simple command ls | grep -o "[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}" no longer works – Mihai Nov 12 '19 at 13:19

2 Answers2

1

Do you really need to store the information in an array? If not, this is IMHO a readable solution:

#!/bin/bash

for file in $(find . -type f); do
  echo "File: $file";
  echo "Date: $(grep 'pattern' <<< "$file")"
done
stephanmg
  • 746
  • 6
  • 17
1

When you pass multi-line strings via here documents, the text is subject to parameter expansion, command substitution and more.

Instead, consider defining the commands to be executed using single quote (avoid all substitutions), and then pass it via the here document. Given that the commands do not use single quote, it relatively simple.

#! /bin/bash
CMD='

 # go in the path where to perform the extraction of dates
cd share/Pictures_G

 # create an array, perform the extraction of dates , populate the array with dates

declare -a all_dates

all_dates=($(ls | grep -o "[0-9]\{4\}-[0-9]\{2\}-[0-9]\{2\}"))
len=${all_dates[@]}
echo "$len"
'
ssh -t -t user@serveradress <<EOT
    $CMD
EOT

Equivalent approach, without the intermediate variable

echo '
 # PUT COMMANDS HERE
 # go in the path where to perform the extraction of dates
cd share/Pictures_G
 # MORE COMMANDS HERE
...
echo "$len"
' | ssh -t -t user@serveradress

**UPDATE 1: Parameterizing the command**

If the command line has to be parametrized to using variables in the calling script, they should be placed into double quotes, instead of single quotes. For example, if TARGET_DIR reference the remote path. Note that the single quote has to be terminated, and the variable should be placed in double quotes for safety.

TARGET_DIR=share/Pictures_G CMD=' # go in the path where to perform the extraction of dates cd '"$TARGET_DIR"'

# create an array, perform the extraction of dates , populate the array with dates

declare -a all_dates

all_dates=($(ls | grep -o "[0-9]{4}-[0-9]{2}-[0-9]{2}")) len=${all_dates[@]} echo "$len" '


dash-o
  • 13,723
  • 1
  • 10
  • 37
  • Thanks for the response, I will try this and I will anounce you what is the result. Have a good day ! – Mihai Nov 15 '19 at 08:26
  • Hello I tried the structure of the first example but the output is $CMD. – Mihai Nov 18 '19 at 07:25
  • Please try without quoting the EOT, AS PER UPDATED ANSWER – dash-o Nov 18 '19 at 07:45
  • Thanks ! The solution works, I have only one concern if I can add arguments from the command line in this situation ?!? (also I will mark the answer as helpful to solve my problem ). – Mihai Nov 18 '19 at 09:34
  • 1
    You should be able to add parameter from the command line. I'll update the first code sample – dash-o Nov 18 '19 at 10:26