Intereting Posts
В то время как Loop Breaking Half Way Through File Где находятся «стек ядра», «Кадры для функций запуска C» и «Кадр для main ()» в макете памяти программы? Символ пользовательского режима для подсказок Bash Некоторые символы фильтруются в bash Ошибка обновления Ubuntu 17.04 «Ожидание автоматического выхода на охрану» apt: переустановить старую версию пакета без изменения зависимых пакетов Ошибка установки OpenVPN через apt перечислить полный путь к файлу, не связывая его с относительным относительным путем Как заблокировать SSH Brute Force через Iptables и как это работает? как использовать порт управления ser2net как сделать поиск текста на терминале напрямую chown не разрешено, но у меня есть доступ на запись. Как я могу взять рекурсивную собственность? Объединение строк с общими значениями Как установить зависимости пакета rpm без установки самого пакета? (RHEL / Fedora) Процесс начинается с inittab, но одновременно останавливается

Кошка с заголовками и номерами строк?

У меня есть файлы, подобные этому

$ cat trapetz x = 0:0.0001:7pi plot(x, sin(x).*cos(x)) Area = trapz(x, sin(x).*cos(x)) $ cat simpson f = inline(sin(x).*cos(x)); Area2 = quad(f, 0, 7pi, 1e-16) 

Я хочу что-то вроде этого

 $ cat -b -t MISSING? trapetz simpson traapetz 1 x = 0:0.0001:7pi 2 plot(x, sin(x).*cos(x)) 3 Area = trapz(x, sin(x).*cos(x)) simpson 1 f = inline(sin(x).*cos(x)); 2 Area2 = quad(f, 0, 7pi, 1e-16) 

или даже лучше, если есть простой способ добавить wc туда:

 $ find |tee |...|wc... I feel now reinventing the wheel, there must be some ready... traapetz: xyz chars 1 x = 0:0.0001:7pi 2 plot(x, sin(x).*cos(x)) 3 Area = trapz(x, sin(x).*cos(x)) simpson: zyx chars 1 f = inline(sin(x).*cos(x)); 2 Area2 = quad(f, 0, 7pi, 1e-16) 

но я получаю

 $ cat -b -t trapetz simpson 1 x = 0:0.0001:7pi 2 plot(x, sin(x).*cos(x)) 3 Area = trapz(x, sin(x).*cos(x)) 4 f = inline(sin(x).*cos(x)); 5 Area2 = quad(f, 0, 7pi, 1e-16) 

Не очень нужна кошка, но какой-то простой инструмент для обмена и демонстрации фрагментов кода, подобных приведенным выше, а не пастебином. Мне нужна стандартная командная строка. Я пытаюсь создать легкую головоломку для приложения codegolf.se, чтобы люди могли легко воспроизводить вещи …

Очень грубая реализация awk:

 BEGIN{ OLDFILENAME=""; } FNR==1{ if (OLDFILENAME != "") { printf("#### Processed (chars: %s - lines: %s)\n", FWC, FLC); } printf("#### Processing: %s\n", FILENAME); OLDFILENAME=FILENAME; FWC=0; FLC=0; } { printf("%04d - %s\n", FNR, $0); FWC = FWC + length($0); FLC = FLC + 1; } END{ if (OLDFILENAME != "") { printf("#### Processed (chars: %s - lines: %s)\n", FWC, FLC); } } 

Выполните awk -f AWKFILE trapetz simpson чтобы получить:

 #### Processing: trapetz 0001 - x = 0:0.0001:7pi 0002 - plot(x, sin(x).*cos(x)) 0003 - Area = trapz(x, sin(x).*cos(x)) #### Processed (chars: 70 - lines: 3) #### Processing: simpson 0001 - f = inline(sin(x).*cos(x)); 0002 - Area2 = quad(f, 0, 7pi, 1e-16) #### Processed (chars: 57 - lines: 2) 

Быстрый скрипт оболочки:

 #!/bin/sh # usage: scriptname file1 file2 ... for file in "$@" do [ -f "$file" ] || continue set -- `wc "$file"` echo "${file}: lines $1 words $2 bytes $3" cat -b -t "$file" done 

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

tail -n +1 trapetz simpson будет печатать каждый файл с ведущим заголовком, дающим имя файла. nl trapetz simpson печатает номера строк, но не имена файлов. Вам нужно будет использовать либо awk либо некоторый shell-клей, чтобы объединить два.

 for x in trapetz simpson; do echo "$x: $(wc -c <"$x") bytes" nl "$x" done 

Вот решение awk, которое печатает счет байта внизу:

 awk ' FNR == 1 && NR != 1 {print "end", fn, chars, "characters"; bytes=0} END {print "end", fn, chars, "characters"} FNR == 1 {print "begin", FILENAME; fn=FILENAME} 1 {chars += 1 + length; printf "%7d ", FNR; print} ' trapetz simpson 

Вот sed + wc + nl + cat (и петля bash )

 set trapetz simpson for file in "$@" ;do { wc -l -m "$file"; cat "$file"; } | sed -nr '1{N;s/(.*)\n(.*)/\2\x01\1/};p' | nl | sed -r '1{s/(.*)\x01 *([0-9]+) +([0-9]+) (.*)$/\4 (\2 lines, \3 chars)\n\1/};$s/.*/&\n/' done; echo "(${#@} files)" 

Вывод

 trapetz (3 lines, 73 chars) 1 x = 0:0.0001:7pi 2 plot(x, sin(x).*cos(x)) 3 Area = trapz(x, sin(x).*cos(x)) simpson (2 lines, 59 chars) 1 f = inline(sin(x).*cos(x)); 2 Area2 = quad(f, 0, 7pi, 1e-16) (2 files) 

Вот sed + grep (не wc, хотя).

Использование sed для ситуаций, таких как это хорошо для практики регулярного выражения и sed juggling, но когда жонглирование становится слишком большим, способность использовать один инструмент (например, awk ) является предпочтительным вариантом.

 grep -nH '.' trapetz simpson | sed -nre 'G; s/^([^:]+):.*\n\1/&/; tp; h; s/^([^:]+).*/\1/p; g; :p; s/^[^:]+:([^:]+):(.*)\n.*/0000\1 \2/; s/^[^ ]*([^ ]{4})(.*)/\1\2/p; g; s/^([^:]+).*/\1/; h' 

Или более читаемое представление 🙂

 grep -nH '.' trapetz simpson | sed -nre ' G # pattern+=nl+hold s/^([^:]+):.*\n\1/&/ # if t printline # when prev==curr branch to printline : new_file # when prev!=curr print header h # hold the pattern s/^([^:]+).*/\1/p # print header (filename) g # get the held pattern : printline # print current line (with line number) s/^[^:]+:([^:]+):(.*)\n.*/0000\1 \2/ # zero pad number s/^[^ ]*([^ ]{4})(.*)/\1\2/p # number width = 4 g # get the held pattern s/^([^:]+).*/\1/ # extract filename h # hold the filename ' 

Вывод

 trapetz 0001 x = 0:0.0001:7pi 0002 plot(x, sin(x).*cos(x)) 0003 Area = trapz(x, sin(x).*cos(x)) simpson 0001 f = inline(sin(x).*cos(x)); 0002 Area2 = quad(f, 0, 7pi, 1e-16) 

Этот список команд:

 echo -e "trapetz\nsimpson" | xargs -I fn sh -c "wc -c fn | sed 's/\(.*\) \(.*\)/\2: \1 chars/';cat -b -t fn" 

Производит этот выход

 trapetz: 73 chars 1 x = 0:0.0001:7pi 2 plot(x, sin(x).*cos(x)) 3 Area = trapz(x, sin(x).*cos(x)) simpson: 59 chars 1 f = inline(sin(x).*cos(x)); 2 Area2 = quad(f, 0, 7pi, 1e-16) 

Версия программного обеспечения:

  • bash 4.2.53
  • GNU sed 4.2.2
  • xargs 4.5.11
  • cat 8.21