2016-10-13 2 views
0

Проблема заключается в следующем У меня есть файл, каждая строка имеет следующую форму:Bash Shell: Infinite Loop

id|lastName|firstName|gender|birthday|joinDate|IP|browser 

я хочу, чтобы отсортировать в алфавитном порядке все firstnames в этом файле и распечатать их по одному на каждой строке, но каждое имя только один раз

я создал следующую программу, но по какой-то причине он создает бесконечный цикл:

array1=() 
while read LINE 
do 
    if [ ${LINE:0:1} != '#' ] 
    then 
     IFS="|" 
     array=($LINE) 
     if [[ "${array1[@]}" != "${array[2]}" ]] 
     then 
       array1+=("${array[2]}") 
     fi 
    fi 
done < $3 
echo ${array1[@]} | awk 'BEGIN{RS=" ";} {print $1}' | sort 

ПРИМЕЧАНИЕ

  • if [ ${LINE:0:1} != '#' ]: эта команда используется, потому что есть комментарии в файле, который я не хочу, чтобы напечатать

  • $3: имя файла

  • array1: используется для всех раздельных имен

+0

Я не вижу никакого способа, которым может быть бесконечный цикл. 'while read' остановится, когда он дойдет до конца файла. – Barmar

+0

Эта команда 'awk' может быть заменена на' tr '' '\ n'' – Barmar

+0

, я не вижу этого, но это то, что на самом деле происходит. Попробуйте запустить его, если хотите. – Clabis

ответ

1

Wow, есть более простой и чистый способ достичь этого, без необходимости связываться с переменной IFS или использовать массивы. Вы можете использовать «для», чтобы сделать это:

Сначала я создал файл с такой же структурой, как ваша:

$ cat file 
id|lastName|Douglas|gender|birthday|joinDate|IP|browser 
id|lastName|Tim|gender|birthday|joinDate|IP|browser 
id|lastName|Andrew|gender|birthday|joinDate|IP|browser 
id|lastName|Sasha|gender|birthday|joinDate|IP|browser 
#id|lastName|Carly|gender|birthday|joinDate|IP|browser 
id|lastName|Madson|gender|birthday|joinDate|IP|browser 

Вот сценарий я написал, используя «для»:

#!/bin/bash 

for LINE in `cat file | grep -v "^#" | awk -F'|' '{print$3}' | sort -u` 
do 
     echo $LINE 
done 

А вот выход из этого сценария:

$ ./script.sh 
Andrew 
Douglas 
Madson 
Sasha 
Tim 

Объяснение:

for LINE in `cat file` 

Создает цикл, который читает каждую строку «файла». Команды между `выполняются linux, например, если вы хотите сохранить дату внутри переменной, вы можете использовать« VARDATE = `date`».

grep -v "^#" 

Опция -v используется для исключения результатов, соответствующих шаблону, в этом случае шаблон «^ #». Символ «^» означает, что «строка начинается с». Поэтому grep -v "^ #" означает "исключить строки, начинающиеся с #".

awk -F'|' '{print$3}' 

Опция -f переключает разделитель столбцов от значения по умолчанию (по умолчанию пробел), чтобы все, что вы положили между "после этого, в этом случае„|“ персонаж. «{print $ 3}» печатает третий столбец.

sort -u 

И команда «sort -u» сортирует имена по алфавиту.

+0

спасибо за объяснение! – Clabis