Need to split string on single quote as delimiter

I have a variable that contains the following string:

FPATH=-rw-rw-r-- 1 user1 dba 0 Aug  7 13:14 /app/F11.3/app/cust/exe/filename1.exe'  -rw-rw-r-- 1 user1 dba 0 Aug 19 10:09 /app/app/F11.3/app/cust/sql/33211.sql'  -rw-r--r-- 1 user1 dba 0 Aug  6 17:20 /app/F11.2/app/01/mrt/file1.mrt' 

I need to split the string based on single quote as delimiter print as below:

Desired Output:

-rw-rw-r-- 1 user1 dba 0 Aug  7 13:14 /app/F11.3/app/cust/exe/filename1.exe  
-rw-rw-r-- 1 user1 dba 0 Aug 19 10:09 /app/app/F11.3/app/cust/sql/33211.sql
-rw-r--r-- 1 user1 dba 0 Aug  6 17:20 /app/F11.2/app/01/mrt/file1.mrt

Below is what I tried but it does not work:

#a=($(echo $FPATH | tr '/'' "\n"))
a=(`echo $FPATH | sed 's/'/\n/g'`)

   for i in "${a[@]}"
do
   printf "ARRAY3:$i"
done

Can you please suggest why is it breaking and how can i get it to work ?

Your sed is not quoted properly.

Try tr , which is used for such manipulation, with sed to remove blank begining of line.

echo $FPATH | tr "'" "\n" | sed "s/^ //g"

Also, you must enclose the content of FPATH variable in double quotes to work.

Please, specify operating system and shell in your future posts.

Hope that helps.
Regards
Peasant.

1 Like

FPATH gets the string by reading it from a file hello.txt.

input="./hello.txt"
while IFS= read -r line
do
  echo "$line"
IFS=': ' read -r ip string <<< "$line"

Below is how I tried your suggestion.

a=`echo $FPATH | tr "'" "\n" | sed "s/^ //g"`
   for i in "${a[@]}"
do
   printf '$i' >> output.txt
done

However, due to single quotes printf '$i' we get the output which is enclosed in single quotes.

If I print without single quotes i.e printf $i then the print statement fails becoz of illegal argument like "-r"

uname -a
Linux mymac 3.10.0-957.12.1.el7.x86_64 #1 SMP Wed Mar 20 11:34:37 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux

Try

printf -- $i

to eliminate that

bash: printf: -r: invalid option

problem incorrectly cited by you. Still, your entire code wouldn't work as

  • you don't create an array
  • even if you created an array by using the a=(...) syntax, it would contain 27 elements to loop across with for .
  • even if you had a 3 element array, the ${a[@]} expansion wouldn't supply those three.
IFS="'" read -a a <<< $FPATH

would create the desired three element array, and e.g.

IFS=$'\n'; echo "${a
[*]}"

would correctly expand it.

Or try

while read LN; do echo $LN; done <<< $(echo "$FPATH" | tr \' $'\n')
1 Like

@RudiC Thank you for the help though it still does not work. Below is the complete snippet.

#!/bin/bash
input="../vars/hello.txt"
while IFS= read -r line
do
    echo "$line"
    IFS=': ' read -r ip string <<< "$line"
    FPATH="$string"
    FPATH=${FPATH//$'u\''/}
    echo "PRINTING4:$FPATH"
    printf  "\n" >> new_test.txt

    while read LN; 
    do
        echo $LN; >> new_test.txt
     #done <<< $(echo "$FPATH" | tr \' $'\n')
     done <<< $(echo "$FPATH" | tr "'" "\n" | sed "s/^ //g")
done < "$input"

I get blank i.e no entries in the new_text.txt instead of the desired output. even when i try the other suggestion i.e done <<< $(echo "$FPATH" | tr \' $'\n')

Debug shows:

PRINTING4:-rw-rw-r-- 1 user1 dba 0 Aug  7 13:14 /app/F11.3/app/cust/exe/filename1.exe'  -rw-rw-r-- 1 user1 dba 0 Aug 19 10:09 /app/app/F11.3/app/cust/sql/33211.sql'  -rw-r--r-- 1 user1 dba 0 Aug  6 17:20 /app/F11.2/app/01/mrt/file1.mrt'
+ printf '\n'
++ echo '-rw-rw-r-- 1 user1 dba 0 Aug  7 13:14 /app/F11.3/app/cust/exe/filename1.exe'\''  -rw-rw-r-- 1 user1 dba 0 Aug 19 10:09 /app/app/F11.3/app/cust/sql/33211.sql'\''  -rw-r--r-- 1 user1 dba 0 Aug  6 17:20 /app/F11.2/app/01/mrt/file1.mrt'\'''
++ tr ''\''' '
'
+ read LN
+ echo -rw-rw-r-- 1 user1 dba 0 Aug 7 13:14 /app/F11.3/app/cust/exe/filename1.exe -rw-rw-r-- 1 user1 dba 0 Aug 19 10:09 /app/app/F11.3/app/cust/sql/33211.sql -rw-r--r-- 1 user1 dba 0 Aug 6 17:20 /app/F11.2/app/01/mrt/file1.mrt
-rw-rw-r-- 1 user1 dba 0 Aug 7 13:14 /app/F11.3/app/cust/exe/filename1.exe -rw-rw-r-- 1 user1 dba 0 Aug 19 10:09 /app/app/F11.3/app/cust/sql/33211.sql -rw-r--r-- 1 user1 dba 0 Aug 6 17:20 /app/F11.2/app/01/mrt/file1.mrt
+ read LN
+ IFS=
+ read -r line -rw-r--r-- 1 user1 dba 0 Aug  6 17:20 /app/app/F11.3/app/cust/mrt/file1.mrt'

It works with the below code:

a=`echo $FPATH | tr "'" "\n" | sed "s/^ //g"`
   for i in "${a[@]}"
do
   printf -- "$i"
done

Thank you everyone for help!!

Another way that doesn't need externals, arrays, loops, or backticks:

INPUT="string'delimited'with'quotes"
OLDIFS="$IFS" ; IFS="'"
printf "%s\n" $INPUT
IFS="$OLDIFS"
1 Like

The correct printf usage is printf "%s\n" "$i" .
The format argument not only elimates the problem with a leading - character but also problems with % characters.

printf can apply the format "%s\n" to multiple arguments.
If your loop does only print you can simply do

a=`echo $FPATH | tr "'" "\n" | sed "s/^ //g"`
printf "%s\n" "${a[@]}"