2013-06-19 3 views
5

У меня есть файл, созданный в окнах с помощью блокнота:сценария не читает последнюю строку файла

26453215432460 
    23543265235421 

    38654365876325 


    12354152435243 

У меня есть скрипт, который будет читать каждую строку, и создать команду, как показано ниже в другом файле для каждой строки и не будет рассматривать пустые строки:

CRE:EQU,264532154324600,432460,1; 

Теперь, если я сохранить входной файл после удара ввести после последней строки номера 12354152435243, то выходной файл состоит команду выше, соответствующие все номера (в том числе последнего 12354152435243:

CRE:EQU,264532154324600,432460,1; 
    CRE:EQU,235432652354210,235421,1; 
    CRE:EQU,386543658763250,876325,1; 
    CRE:EQU,123541524352430,435243,1; 

но если сохранить файл, не задев ввести после того, как последний номер введенные т.е. после этого 12354152435243, то после выполнения сценария, я не вижу выходной файл имеет команду для последнего номера :

CRE:EQU,264532154324600,432460,1; 
    CRE:EQU,235432652354210,235421,1; 
    CRE:EQU,386543658763250,876325,1; 

Может кто-нибудь объяснить ошибку в коде:

while read LINE 
    do 
    [ -z "$LINE" ] && continue 
    IMEI=`echo $LINE | sed 's/ //g' | sed -e 's/[^ -~]//g'` 
    END_SERIAL=`echo $IMEI | cut -c9- | sed 's/ //g' | sed -e 's/[^ -~]//g'` 
    echo "CRE:EQU,${IMEI}0,${END_SERIAL},${list},,${TODAY};" >> /apps/ins/list.out 
    done < "${FILE_NAME}" 

любезно помочь

+0

Интересно, если это что-то делать с Windows, против * NIX окончаниях строк. (Наверное, нет, но вы никогда не знаете ...) Попробуйте открыть файл в шестнадцатеричном редакторе, таком как HexFiend, и посмотрите на последнего персонажа. – daviewales

+0

Да, я думал что-то с возвратом каретки или символом '\ n' –

+0

Как это помогает? –

ответ

4

Использование

grep . "${FILE_NAME}" | while read LINE 

или

while read LINE 
do 
.... 
done < <(grep . "${FILE_NAME}") 

Grep менее чувствительна к линейному концу, и вы получите пустой строки пропуска для свободно ... :)

Честно говоря, никогда не пробовали окна, все выше в порядке для unix ...

EDIT Explana Тион:

сделать следующий файл:

echo -n -e 'line\n\nanother\nno line ending here>' >file.txt 

файл содержит 4 строки (хотя последняя "линия" не является "правильным" один)

line 

another 
no line ending here> 

Обычные процедуры оболочки, как read или wc ищет окончания строки.Поэтому

$ wc -l file.txt 
     3 file.txt 

При оглавлению для '' (пустой строки) Grep возвращает каждую строку, где найдена строка, так

$ grep '' file.txt 

печатает

line 

another 
no line ending here> 

Когда Grep выводит найденный линии - гарантирует, что в конце существует один `\ n ', поэтому

$ grep '' file.txt | wc -l 

возвращает

4 

поэтому для таких ситуаций, лучше использовать grep с -c (счета), а не wc.

$ grep -c '' file.txt 
4 

Теперь, . точка. Точка означает любой символ. Итак, когда вы grepping для ., вы получаете все строки, содержащие хотя бы один символ. И, следовательно, он пропустит все строки, что не содержит символов = пропускает пустые строки. Итак,

$ grep . file.txt 
line 
another 
no line ending here> 

еще раз, с добавленной строкой, заканчивающейся до последней строки (и пропуская пустую строку). Помните, что (пробел) тоже является символом, поэтому, когда строка содержит только одно пространство, оно НЕ ПУСТО. Счетные непустые строки

$ grep . file.txt | wc -l 
     3 

или быстрее

$ grep -c . file.txt 
3 
+0

Отлично работает. Будете ли вы любезны, просто чтобы объяснить логику того, почему я greppin '.' из' $ FILE'. В любом случае, большое спасибо за этот трюк. Приветствия –

+0

@Siddharth добавил объяснение – jm666

+0

Большое спасибо, это, безусловно, поможет –

0

Если вы делаете help read, он говорит для -d delim continue until the first character of DELIM is read, rather than newline.

Таким образом, чтение будет продолжаться до тех пор, пока оно не достигнет \n или если вы укажете -d delim.

Таким образом, вы, вероятно, нужно изменить DELIM или вы можете попробовать read -e

+0

'читать -e' не работает для меня' эхо -n $ «а \ пь» | во время считывания -Ex, делать эхо $ х, done' '-ksh: чтение : -e: неизвестный параметр Usage: чтение [-ACprsv] [-d разделитель] [-u FD] [-t таймаут] [-n NCHAR] [-N NCHAR] [? вар подсказка] [вар ...] ' использование также '' delim' с -d' опции увеличит свой код, чтобы успокоить несколько строк, как я должен сначала скопировать исходный файл с персонажем, действующим в качестве разделителя для каждой непустой строки, то я должен кормить . это 'чтения -d delim' –

0

read Nees конец строки для чтения входных данных. Попробуйте

echo -n $'a\nb' | while read x ; do echo $x ; done 

Только печатает a.

+0

' чтения -e' не работает для меня 'эхо -n $«а \ пь»| во время считывания -ex, делать эхо $ х, done' ' -ksh: следующим образом: -e: неизвестно option' 'Использование: чтение [-ACprsv] [-d разделитель] [-u Fd] [-t таймаут] [-n NCHAR] [-N NCHAR] [? уаг подсказка] [вар ... ] 'Разве это не работает для k-оболочки? –

+0

@ Сиддха rth: «-e» не был важен, я просто пытался, что предложил nkon. – choroba

0

читать прочтет недо новую линию было найдено, и, когда он находит новую строку, то он вернет вам строку. Но если файл заканчивается без новой строки, прочитайте это как ошибку. Таким образом, даже если read задал возвращаемую переменную с прочитанной до сих пор строкой, код возврата read установлен для указания ошибки. Теперь while read ... это тело цикла будет выполняться только в том случае, если команда выполняется с успехом, что здесь не так. Таким образом, вы пропустите последнюю строку.

Для преодоления этого условия вы можете изменить условие, чтобы также проверить, что возвращаемая переменная пуста или нет. Следовательно, условие выполняется успешно, даже если чтение не выполняется, поскольку переменная уже установлена ​​до конца файла.

Это не относится к строке, заканчивающейся в разных ОС, я имею в виду, что это как-то связано, но точная основная причина всегда read не может найти новую строку в конце строки/файла, а последняя строка - отсутствует тело цикла.

Ниже приведен пример

[[bash_prompt$]]$ echo -ne 'hello\nthere' > log 
[[bash_prompt$]]$ while read line; do echo $line; done < log 
hello 
[[bash_prompt$]]$ while read line || [ -n "$line" ]; do echo $line; done < log 
hello 
there 
[[bash_prompt$]]$ 
Смежные вопросы