0

I have a text file and I want to create an array out of it like this: array=["line1","line2",...].

Here are the first lines of my text:

Hamlet 

William Shakespeare 

Edited Barbara B Mowat Paul Werstine 

Michael Poston Rebecca Niles 

Folger Shakespeare Library 

httpwwwfolgerdigitaltextsorgchapter5playHam 

Created Jul 31 2015 FDT version 092 

Characters Play 

line 17 POLONIUS father Ophelia Laertes councillor King Claudiusthis line substituted  
GHOST  

And the output should be in the form:

lines=["Hamlet"
,"William Shakespeare"
,"Edited Barbara B Mowat Paul Werstine "
,"Michael Poston Rebecca Niles"
,"Folger Shakespeare Library"
,"httpwwwfolgerdigitaltextsorgchapter5playHam"
,"Created Jul 31 2015 FDT version 092"
,"Characters Play"
,"line 17 POLONIUS father Ophelia Laertes councillor King Claudiusthis line substituted","GHOST"]
0

You can do this using sed tool as follows:

sed - e '
       s/^[[:blank:]]*//;s/[[:blank:]]*$//
       s/"/\\"/g;H;$!d;g
        s/\n/","/g;s/.*/"&"/
 ' input

When each line iz read in, trim the leading nd trailing whitespace from it. Escape all double quotes. Append into the hold space and when last line seen, change all newlines to separator of array elements.

  • i found it very useful! could you please explain about the code? – Reza Jan 16 at 7:59
  • @ Reza, i have added explanations for each sed command used in a below answer. Please go have a look there. – Rakesh Sharma Jan 16 at 12:20
1

Assuming the file does not contain blank lines:

mapfile -t array <file

The -t removes the newline from each read line. This will create the array array from the lines in file if using bash.

It's unclear whether you want the result to be the array itself or the textual representation of the array that you display.

To get the particular output that you ask for:

mapfile -t array <file
printf '"%s"\n' "${array[@]}" | { mapfile -t arr; IFS=','; printf 'lines=[%s]\n' "${arr[*]}"; }

This reads the lines into the array array as before. The next printf statement will add double quotes around each element of the array, and send it off to a new mapfile command that will read the modified data into a new temporary array arr. This array is used in a printf statement that formats its elements in the way that you request, with commas inserted between the double quoted elements.

Using awk instead (and not storing the lines in a shell array at all):

awk -v OFS=',' '
    { line[NR] = $0 }
    END {
        for (i=1; i<=NR; ++i)
            $i = "\"" line[i] "\""
        printf("lines=[%s]\n", $0);
    }' file

This reads each line into an awk array. At the end, double quotes are added to the elements and they are assigned to the output fields (in the for loop). The printf statement formats the output in pretty much the same way as in the shell code example. $0 represents the current record, whose fields we've just been assigning.

  • it's great! there's a minute problem! i want to remove the spaces from both sides of all elements, if it has any. for ex: " Michael Poston Rebecca Niles " should turn to "Michael Poston Rebecca Niles", or "Hamlet " to "Hamlet". – Reza Jan 15 at 13:23
  • @Reza Pre-process your data to remove the flanking space characters. Passing it through sed 's/^[[:blank:]]*//; s/[[:blank:]]*$//' would remove any blanks at the start and end of each line. – Kusalananda Jan 15 at 18:10
0
IFS=$'\n'
array=( $(awk '{print "\"" $0 "\""}' input_file) )

For every line in the input_file, from top to bottom, the awk command in the command substitution does the following:

  1. Surround the line with a pair of double quotes.
  2. End the double-quoted line with a newline character.
  3. Print the resulting line to the standard output.

However, instead of printing to the standard output, the result of the awk command is used to replace the entire command substitution. The replacement is the result of the command substitution.

Next, word-splitting is then applied to the result of the command substitution. The word-splitting identifies any sequence of characters not including the IFS character but terminated by an IFS character to be a distinct "word". Therefore, in this particular case, a "word" is any line (from the input_file) that has been enclosed with a pair of double quotes by the awk command.

Since the command substitution is enclosed by the outermost pair of parentheses (), the result of awk is placed in between those parentheses, and the shell treats the entire parentheses including all the substituted tokens in between (which are your lines placed side-by-side each enclosed by a pair of double quotes) as an array.

NOTE:

  • After the array assignment, you might want to reset the shell variable IFS back to its original value of a space, a tab, and a newline.
0

Its really easy to do it via below python script

array = [array.rstrip('\n') for array in open("YourFilename")]

print array

For windows I executed it as below:

C:\Users\XXX>py.exe Python 3.6.8 (tags/v3.6.8:3b436a57, Dec 23 2018, 23:31:17) [MSC v.1916 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information.

array = [array.rstrip('\n') for array in open("c:/Users/XXX/Documents/sample.txt")]

print (array)

['Hamlet ', 'William Shakespeare ', 'Edited Barbara B Mowat Paul Werstine ', 'Michael Poston Rebecca Niles ', 'Folger Shakespeare Library ', 'httpwwwfolgerdigitaltextsorgchapter5playHam ', 'Created Jul 31 2015 FDT version 092 ', 'Characters Play ', 'line 17 POLONIUS father Ophelia Laertes councillor King Cl']

>

  • sorry! it didn't work!! – Reza Jan 15 at 13:13
  • What error are you getting? I tried it here and it works perfectly. Hope you are using python script for executing it – Ravi Jan 15 at 15:54
  • i wrote this script in python 3.6: array = [array.rstrip('\n') for array in open("C:\\Users\\Reza\\Downloads\\final_text.txt")] print (array) but nothing happened! – Reza Jan 15 at 17:14
  • I executed the same in windows as shown above in answer and it works, I have edited my answer for windows, seems you didn't mentioned the path correctly – Ravi Jan 15 at 19:32
0
sed - e '
   s/^[[:blank:]]*//;   # trim any leading blanks from the current line read in
   s/[[:blank:]]*$//;   # trim any trailing blanks from the current line read in
   s/"/\\"/g;           # escape any double quotes which might exist in the current line read in
   H;1h;                # append the current line to the hold space, in case of first store as is
   $!d;                 # not yet EOF, drop everything and go back to reading the next line
   g;                   # @ EOF, fetch the hold space: line1\nline2\nline3\n....\nlineEND
   s/\n/","/g;          #  line1","line2","line3","....","lineEND
   s/.*/"&"/;           # "line1","line2","line3","....","lineEND"
' input

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.