Отображение пустых строк командой cat


11

У меня есть список файлов .txt, ниже:

-rw-rw-r-- 1 root dev 11 May 16 12:18 20_SumActive.txt  
-rw-rw-r-- 1 root dev 11 May 16 12:18 22_SumActive.txt  
-rw-rw-r-- 1 root dev  7 May 16 12:18 24_SumActive.txt  
-rw-rw-r-- 1 root dev  0 May 16 12:18 26_SumActive.txt  
-rw-rw-r-- 1 root dev  0 May 16 12:18 28_SumActive.txt  

Выход:

kpgmeddev01> cat 2[0-8]_SumActive.txt   
Sum: 47760  
Sum: 72000  
Sum: 0

Как получить вывод, как показано ниже:

Sum: 47760  
Sum: 72000  
Sum: 0  
[Blank]  
[Blank]  

Нужно руководство.


Есть ли в файлах более одной строки?
Ройма

Нет, только 1 строка
Fewong

1
Когда вы написали [Blank], вы имели в виду эти 7 символов или намеревались указать пустую строку?
Ройма

1
Не используя кошку. Не сдерживайте себя.
Ctrl-Alt-Delor

Ответы:


20

catне может вывести данные, которых нет в файлах. Если файл пуст, у него даже нет символа новой строки для предоставления пустой строки в качестве вывода.

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

Вот как вы используете GNU awkдля обеспечения этого (это изменяет пустые файлы):

awk 'ENDFILE { if (FNR == 0) printf("\n") >>FILENAME }' 2[0-8]_SumActive.txt   

ENDFILEБлок будет выполнен после окончания считывания любого из файлов. Если FNRноль, мы никогда не видели никаких строк в файле, поэтому мы вставляем в него одну новую строку. Затем сценарий продолжается со следующего файла.

Затем вы можете использовать, catкак вы сделали в вопросе.


В качестве альтернативы, без изменения файлов, используя GNU awk вместо cat :

awk 'ENDFILE { if (FNR == 0) printf("\n") } 1' 2[0-8]_SumActive.txt

Это делает то же самое обнаружение пустых файлов, что и выше, но печатает новую строку в стандартный вывод, а не в файл. Значение 1в конце может быть заменено на { print }и приведет к выводу всех данных в непустых файлах.


Альтернативно, цикл оболочки (должен работать в любой оболочке POSIX):

for name in ./2[0-8]_SumActive.txt; do
    if [ -s "$name" ]; then
        cat "$name"
    else
        printf '\n'
    fi
done

-sТест будет истиной , если файл существует и имеет больший размер , чем ноль.


Если вы хотите, чтобы буквальная строка [Blank]выводилась для пустых файлов, просто вставьте эту строку перед \nвызовами printfвыше (это также будет работать в awkкоде).


2
@ Fewong Хорошо! Если это решит вашу проблему, пожалуйста, подумайте о принятии ответа .
Кусалананда

@Fewong: Или примите другой ответ, который поможет вам еще лучше - это хорошая практика, чтобы дать каждому часовому поясу шанс, так что нет никакой спешки.
MSalters

@Fewong Определенно не спешите. Стефане также написала короткое и компактное решение, которое выглядит многообещающим.
Кусалананда

@Kusalananda, спасибо, и я проверил это сработало.
Fewong

16

С perl

perl -0777 -pe 's/\n?\z/\n/' 2[0-8]_SumActive.txt

Который добавляет символ новой строки, если отсутствует в конце, поэтому выдает пустую строку для пустых файлов, но также добавляет новую строку для непустых файлов, которые пропускают (и в конечном итоге будет объединен в одну строку с cat).


Хорошее предложение
erTugRul

13

(Это не совсем то, что вы спрашиваете, но :) В таких ситуациях я предпочитаю использовать head

$ head -z 2[0-8]_SumActive.txt
==> 21_SumActive.txt <==
Sum: 47760  
Sum: 72000  
Sum: 0  

==> 22_SumActive.txt <==

==> 25_SumActive.txt <==

==> 28_SumActive.txt <==

Обычно это то, что вы хотите. Если нет, то это легко sedпотом


12

С xargsи grepвы можете попробовать что-то вроде:

$>ls | xargs -n1 sh -c 'grep "" $0 || echo "[Blank]"'
Sum: 47760
Sum: 72000
Sum: 0
[Blank]
[Blank]

4
Возможно, не самое быстрое решение (разветвление оболочки для каждого файла), но пока только одно, которое действительно будет работать, если у вас есть миллионы таких файлов в текущем каталоге (без использования расширений оболочки и достижения ограничения ARGV).
Матия Налис

1
@MatijaNalis: очень верно! Но вы действительно не заботитесь о 5 файлах.
FloHimself

6

Предполагая, что под [Blank]вами подразумеваются буквальные пустые строки, это должно сработать:

paste -s 2[0-8]_SumActive.txt

6

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

for f in 2[0-8]_SumActive.txt;
do
    [[ -s "$f" ]] && awk 1 "$f" || echo '[Blank]'
done

Я использовал awk 1 "$f"вместо того, cat "$f"потому что awkгарантирует завершение вывода файла с новой строки.

В вашем вопросе, если вы предполагали, что это [blank]должен быть не буквальный, а просто пустая строка, вы можете реализовать это, используя приведенный выше код и удалив '[Blank]'из конца echoоператора.


5

Я предполагаю, что ваши файлы 26_SumActive.txt и 28_SumActive.txt пусты и вам нужны пустые строки при отображении их содержимого

Для этого вы можете просто просмотреть список файлов и просмотреть их содержимое, а если файл пуст, вывести пустую строку.

[ -s FILE ] Истинно, если ФАЙЛ существует и имеет размер больше нуля.

$ for i in $(ls 2[0-8]_SumActive.txt) ; do  cat $i;  if [ ! -s $i ]; then echo -e ""; fi; done
Sum: 47760  
Sum: 72000  
Sum: 0  
[ Blank Line]
[ Blank Line ]

1
Или if [ -s $i ]; then cat $i; else echo -e ""; fi;. Еще +1 для простого теста, использующего только стандартную функциональность оболочки.
MSalters

2
Или просто cat "$i"; test -s "$i" || echo- не нужно для этого громоздких ifили непереносимых echoфлагов.
Тоби Спейт

1
cat 2[0-8]_SumActive.txt -

где - позволит кошке читать со стандартного ввода.

Итак, после отображения содержимого ваших файлов кошка будет ждать вашего ввода. Вы можете сделать желаемый ввод, нажав ввод для буквенных пробелов или [Пробел], если это то, что вы хотите. После каждого ввода нажмите ввод, как только все данные введены, нажмите ^ D (Ctrl + D) и все готово.

PS: для каждого входа вы получите соответствующий вывод.

cat 2[0-8]_SumActive.txt - 4[0-8]_SumActive.txt

При этом вы можете поместить пробелы или что-то еще, что вы хотите, между двумя последовательностями выходов.


Исходя из этого, вы могли бы просто предложить catв качестве решения и позволить оператору, что они хотят.
Ройма
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.