Bash - colocando a primeira palavra de cada linha em um array

2

Estou tentando colocar a primeira palavra de cada frase em uma matriz.

O que estou fazendo de errado?

#!/bin/bash
file_name=$1
content=$(cat $file_name)
content=${content//"\n"/" "}
content=${content//". "/"\n"}
declare -A arr
cat $content| while read line;
do 
   line=($line)
   word=${line[0]}

if [[ ${arr[$word]} == '' ]] 
then
    arr[$word]=1
else
    let arr[$word]=${arr[$word]}+1
fi

done
    
por S.E 12.04.2018 / 19:17

2 respostas

0

A menos que você tenha que fazê-lo em bash puro (por motivos pedantes?), use cut para produzir a lista de "primeiras palavras" em um loop for wrd in $(cut "-d " -f1 $file_name ) ; do ou se sua lista de palavras for maior que xargs --no-run-if-empty --show-limits </dev/null , use cut e xargs .

Em seu código existente, parece que você está tentando obter todos os dados e usando apenas bash " Parameter Expansion ", processe-o em content (um uso indevido de bash variáveis) e use como um nome de arquivo ( cat $content ), para achatar os dados e processar uma linha de cada vez.

Claro, leia man cut , man xargs e man bash .

    
por waltinator 12.04.2018 / 20:34
0

Crie um arquivo de entrada chamado ~/Documents/FirstWord.txt contendo:

Sample data file --> FirstWord.txt

This is a simple little input file used
as to test the bash script FirstWord.sh

There are three paragraphs separated by
one blank line. The output from this file
is "Sample", "This", "as", "one" and "is".

Crie um script bash chamado ~/Downloads/FirstWord.sh contendo:

!/bin/bash
file_name=$1
content=$(cat $file_name)
content="${content//"\n"/" "}"      # <-- You were missing double quotes around
content="${content//". "/"\n"}"     #     ${content//...} needed when spaces occur.
echo "$content" > /tmp/ContentFile  # Create temporary file of massaged data.

declare arr         # Define regular array.

while IFS='' read -r line || [[ -n "$line" ]]; do
#      ^ 1.       ^ 2.          ^ 3.

# 1. IFS='' (or IFS=) prevents leading/trailing whitespace from being trimmed.
# 2. -r prevents backslash escapes from being interpreted.
# 3. || [[ -n $line ]] prevents the last line from being ignored if it doesn't end with a \n (since read returns a non-zero exit code when it encounters EOF).

# ** Above explanation from: https://stackoverflow.com/a/10929511/6929343

    first=${line%% *}   # Extract first word from line.
    arr+=($first)       # Assign $first to next available array entry.

done < /tmp/ContentFile # <-- In bash it is best to read files at end of while loop.

echo ${arr[@]}          # Dump array contents to screen.
rm -f /tmp/ContentFile  # Remove temporary file.

# +============================================================================+
# | Original program with comments below                                       |
# +----------------------------------------------------------------------------+

# declare -A arr                        <-- We don't need associative array.

# cat $content| while read line;        <-- Unconventional method
# do                                    <-- I usually append to line above.
    # line=($line) <--- Assigning a variable to itself has no effect.
    # word=${line[0]} < Not sure what would be accomplished by this.

    # if [[ ${arr[$word]} == '' ]]      <-- I've indented for readability.
    # then
    #     arr[$word]=1                  <-- "word" isn't a counter, won't work.
    # else
    #     let arr[$word]=${arr[$word]}+1<-- Once again "word" isn't a counter.
    # fi
# done                                  <-- Where input to while loop shoud be.

Salve os dois arquivos e, em seguida, no tipo de terminal:

~$ cd Downloads
~/Downloads$ chmod a+x FirstWord.sh
~/Downloads$ ./FirstWord.sh FirstWord.txt
Sample This as There one is
    
por WinEunuuchs2Unix 14.04.2018 / 02:25