Bash - помещение первого слова каждой строки в массив

Я пытаюсь поместить первое слово от каждого предложения в массив.

Что я делаю неправильно?

#!/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
2
задан 12 April 2018 в 21:21

2 ответа

Если Вы не должны выполнять в нем чистый bash (по педантичным причинам?), использовать cut произвести список "первых слов", любого в a for wrd in $(cut "-d " -f1 $file_name ) ; do цикл, или если Ваш список слов больше, чем xargs --no-run-if-empty --show-limits </dev/null, использовать cut и xargs.

В Вашем существующем коде Вы, кажется, пытаетесь хлебать все данные и использование только bash "Parameter Expansion", обработайте его в content (неправильное употребление bash переменные), затем используйте его в качестве имени файла (cat $content), чтобы выровнять данные и обработать 1 строку за один раз.

Конечно, читать man cut, man xargs, и man bash.

0
ответ дан 2 December 2019 в 07:48

Создайте входной названный файл ~/Documents/FirstWord.txt содержа:

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".

Создайте названный сценарий удара ~/Downloads/FirstWord.sh содержа:

!/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.

Сохраните эти два файла и затем в терминальном типе:

~$ cd Downloads
~/Downloads$ chmod a+x FirstWord.sh
~/Downloads$ ./FirstWord.sh FirstWord.txt
Sample This as There one is
0
ответ дан 2 December 2019 в 07:48

Другие вопросы по тегам:

Похожие вопросы: