Вывод диагонали файла

Вы можете использовать

du -sh directory/

и

du -sh filename

чтобы узнать место, занимаемое папкой или файлом.

df -h

покажет использование диска в человекочитаемом формате -h делает это.

Существует также программа на основе gui под названием Disk Usage Analyzer.

6
05.07.2017, 16:30
7 ответов

решение awk, не такое элегантное, как решение @don _chrissti, но работает там, где не квадрат.

awk -F, '{a=a$++n" "}END{print a}' file
7
27.01.2020, 20:20
  1. Оболочка POSIX :

    n=0
    while IFS=',' && read x ; do
        set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done < inputfile
    
  2. bashможно более кратко:

     n=0; while IFS=',' read -a x ; do echo "${x[((n++))]}" ; done < inputfile
    

Обратите внимание, что легко получить диагонали для всех четырех поворотов данных путем фильтрации только по tacи rev, (или tac--, если данные представляют собой квадрат . ].csv массив ). Примеры оболочки POSIX , но сначала создайте несколько новых асимметричных входных значений:

seq 25 | paste -d, - - - - - | tee asym_input

Выход:

1,2,3,4,5
6,7,8,9,10
11,12,13,14,15
16,17,18,19,20
21,22,23,24,25
  1. A\диагональ слева направо , (вопрос OP ,с другим вводом):

    n=0
    while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done < asym_input
    

    Выход:

    1
    7
    13
    19
    25
    
  2. A/слева направо по диагонали:

    n=0
    tac asym_input | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done
    

    Выход:

    21
    17
    13
    9
    5
    
  3. A/справа налево по диагонали:

    n=0
    rev asym_input | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done | rev
    

    Выход:

    5
    9
    13
    17
    21
    
  4. A\справа налево по диагонали:

    n=0
    tac asym_input | rev | while IFS=',' && read x ; do
         set -- $x ; shift $n ; echo "$1" ; n=$((n+1))
    done | rev
    

    Выход:

    25
    19
    13
    7
    1
    
3
27.01.2020, 20:20

Python и numpy

Исследуемые входные данные можно рассматривать как матрицу или двумерный -массив. Теперь, если мы подойдем к проблеме с этой точки зрения, есть несколько вычислительных инструментов, которые можно использовать для манипулирования матрицами. В частности, это позволяет модуль Python numpy. Таким образом, мы могли бы использовать две вещи -функцию loadtxt()и diagonal()для извлечения нужных данных:

$ python -c 'import sys,numpy;a=numpy.loadtxt(sys.argv[1],dtype=int,delimiter=",");print( a.diagonal() )'  input.txt                                                                    
[1 7 3 9 5]

Теперь это большая часть проделанной работы. Чтобы сделать вывод красивым, нам просто нужно преобразовать полученные данные в строки и создать строку, разделенную пробелом -, из отдельных строк. Вот так:

$ python -c 'import sys,numpy;a=numpy.loadtxt(sys.argv[1],delimiter=",");print(" ".join( [ str(int(i)) for i in a.diagonal() ]))'  input.txt                                            
1 7 3 9 5

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

#!/usr/bin/env python
import sys
import numpy as np

for filename in sys.argv[1:]:
    data=np.loadtxt(filename,delimiter=",")
    diag = data.diagonal()
    result_string = " ".join( [ str(int(i)) for i in diag ] ) 
    print(result_string)
5
27.01.2020, 20:20
sed -ne '
   y/,/\n/;G;s/\n$//

   y/\n_/_\n/;:loop
      /_$/{
         s///
         s/^[^_]*_//
         bloop
      }
   y/\n_/_\n/;P

   s/.*//;H
' input.file | paste -sd' '

Мы ведем реестр по полям, -разделенным запятыми, которые нужно пропустить в пространстве шаблонов в пространстве удержания.

Цикл отсекает пространство шаблона с обоих концов, чтобы достичь ситуации, когда крайний левый созрел для печати. Мы можем представить, что это горящая свеча с обоих концов (, однако скорость горения различна ). Спереди мы вырезаем поле, разделенное запятой -, а с конца опускаем замыкающее \n. Сжигание продолжается до тех пор, пока не останется завершающих строк новой строки.

И теперь диагональный элемент находится впереди пространства шаблона.

Артефакт y/\n_/_\n/предназначен для обхода того факта, что POSIX sedне имеет знака новой строки, инвертированного внутри класса символов, [^\n].

В качестве последнего шага для текущей строки область хранения увеличивается. Команда pasteпредназначена для получения вывода в одной строке.


Если все поля в вашем CSV-файле числовые, вы также можете использовать следующий фрагмент dc. trпредназначен для удаления запятых, поскольку поля постоянного тока разделены пробелами, а отрицательные числа начинаются с _, а не -

.
tr ',-' ' _' < file | dc -e '[q]sq [s0zlk<a]sa [?z0=qzlk1+dsk<an32ancz0=?]s? 0skl?x[]p'

Мы определяем 3 макроса: qдля выхода после завершения, aдля цикла для удаления элементов с конца (извлечения )и ?для настройки цикла для выполнения строки -ориентированное чтение и вызов макроса a, а затем печать элемента diagnol, который теперь открыт.

tr... |
dc -e '
   # quit macro
   [q]sq

   # macro to pop elements from stack till they are more than counter k
   [s0 zlk<a]sa

   # do-while loop for reading lines
   [
      ?z0=q       # quit if line read is empty
      zlk1+dsk<a  # increment the counter k and compare it against NF (z) call a if >
      n 32an      # print the diagonal element and a space (no newlines)
      c z0=?      # invoke myself again 
   ]s?

   # main
   0sk  # initialize the counter k
   l?x  # call the macro ? to start the file read-in loop
   []p  # print a trailing newline
'

Выход:

1 7 3 9 5
3
27.01.2020, 20:20

Вот еще один вариант использования awk:

awk -F, '{printf "%s%s",$NR,NR==NF?ORS:OFS}' file 
1 7 3 9 5
1
27.01.2020, 20:20

Решение на основе оболочки/выемки -:

index=1
while read line
do
  cut -d, -f ${index} <<< "$line"
  index=$((++index))
done < input
1
27.01.2020, 20:20

Аннотация:

  1. Квадрат.....:awk -F, '{printf(NR==1?$NR:" "$NR)}END{printf("\n")}' file
  2. Прямоугольный:

    awk -F, ' NR==1{printf($1);next}
              {printf(" "$(NR>NF?NF:NR))}END{printf("\n")}
            ' file`
    
  3. Другие диагонали:

    awk -F, -vdiag=9 -vdir=-1 '
        {d=(NR-1)*(dir>0?1:-1)+1+diag;d=(d<1?1:d);d=(d>NF?NF:d)}
        {printf("%s%s",NR==1?"":" ",$d)}
        END {printf("\n")}
     ' file
    
  4. Posix, который выбирает номер диагонали и направление /против \. (код длинный, прочтите его в конце этого поста ).


Детали

Квадратная матрица

С awk наиболее элегантным решением является:

$  awk -F, '{print $NR}' file
1
7
3
9
5

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

$ awk -F, -v ORS=" " '{print $NR}' file; echo
1 7 3 9 5 

Если вы должны иметь выходные данные без пробелов в конце:

$  awk -F, '{printf(NR==1?$NR:" "$NR)}END{printf("\n")}' file
1 7 3 9 5

Прямоугольный

Для файла, например, с этим:

$ cat file
1,2,3,4,5
6,7,8,9,0
1,2,3,4,5
6,7,8,9,0
1,2,3,4,5
a,b,c,d,e
f,g,h,i,j
k,l,m,n,o
p,q,r,s,t
u,v,w,x,y

Приведенное выше решение будет печатать пробелы:

$ awk -F, '{printf(NR==1?$NR:" "$NR)}END{printf("|\n")}' file
1 7 3 9 5     |

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

$ awk -F, 'NR>NF{exit}{printf(NR==1?$NR:" "$NR)}END{printf("|\n")}' infile
1 7 3 9 5|

Если вы хотите напечатать последнее поле в любой строке, где NR > NF:

$ awk -F, 'NR==1{printf($1);next}{printf(" "$(NR>NF?NF:NR))}END{printf("|\n")}' file
1 7 3 9 5 e j o t y|

Другие диагонали

Если необходима диагональ, отличная от «главной диагонали», мы можем указать, что, установив для переменной diag значение, отличное от 0 (0 является главной диагональю в этом коде):

$ awk -F, -vdiag=3   '   {d=NR+diag;d=(d<1?1:d);d=(d>NF?NF:d)}
                         {printf("%s%s",NR==1?"":" ",$d)}
                         END {printf("\n")}
                     ' file
4 0 5 0 5 e j o t y

Обратите внимание, что значение diag может быть отрицательным:

 $ awk -F, -vdiag=-3 '   {d=NR+diag;d=(d<1?1:d);d=(d>NF?NF:d)}
                         {printf("%s%s",NR==1?"":" ",$d)}
                         END {printf("\n")}
                     ' infile
 1 6 1 6 2 c i o t y

И диагональ могла бы быть как /вместо \с большим количеством математики:

$ awk -F, -vdiag=4 -vdir=-1 '
    {d=(NR-1)*(dir>0?1:-1)+1+diag;d=(d<1?1:d);d=(d>NF?NF:d)}
    {printf("%s%s",NR==1?"":" ",$d)}
    END {printf("\n")}
' file
5 9 3 7 1 a f k p u

$ awk -F, -vdiag=9 -vdir=-1 '
    {d=(NR-1)*(dir>0?1:-1)+1+diag;d=(d<1?1:d);d=(d>NF?NF:d)}
    {printf("%s%s",NR==1?"":" ",$d)}
    END {printf("\n")}
' infile
5 0 5 0 5 e i m q u

Posix оболочка

С другим входным файлом:

$ printf '%s\n' {1..6}{1..5} 7{1..3} | pr -ta -5 -s',' | tee inputfile
11,12,13,14,15
21,22,23,24,25
31,32,33,34,35
41,42,43,44,45
51,52,53,54,55
61,62,63,64,65
71,72,73

Эквивалентом awk в Posix-совместимой оболочке может быть:

diagPosix(){ diag=${1%%[!0-9+-]*} dir=$(((${2:-1}>0)?1:-1)) n=0 a=""
             while read x ; do
#                echo "testing $n $x"
                 IFS=',' eval 'set -- $x'  # Place values in pos parms.
                 a=$(( diag + n*dir    ))  # calculate position a
                 b=$(( (a<0)?0:a       ))  # low limit is zero (0)
                 d=$(( (b>$#-1)?$#-1:b ))  # upper limit is ($#-1)
#                echo "a=$a b=$b d=$d #=$# n=$n"
                 shift $d                  # remove leading parms
                 printf '%s' "$s" "$1"     # print parm (and an space)
                 s=" "                     # Next loop will have space.
                 n=$((n+1))                # In which line are we?
             done <"${3:-inputfile}"
             echo 
           }
diagPosix "$@"

, что с учетом введенных выше данных,будет работать следующим образом:

$./script 0 1 inputfile
11 22 33 44 55 65 73

$./script -2 1 inputfile
11 21 31 42 53 64 73

$./script 4 -1 inputfile
15 24 33 42 51 61 71

Код был протестирован в некоторых оболочках и работает хорошо.

ash             : 11 22 33 44 55 65 73
/usr/bin/yash   : 11 22 33 44 55 65 73
y2sh            : 11 22 33 44 55 65 73
dash            : 11 22 33 44 55 65 73
zsh/sh          : 11 22 33 44 55 65 73
b203sh          : 11 22 33 44 55 65 73
b204sh          : 11 22 33 44 55 65 73
b205sh          : 11 22 33 44 55 65 73
b30sh           : 11 22 33 44 55 65 73
b32sh           : 11 22 33 44 55 65 73
b41sh           : 11 22 33 44 55 65 73
b42sh           : 11 22 33 44 55 65 73
b43sh           : 11 22 33 44 55 65 73
b44sh           : 11 22 33 44 55 65 73
lksh            : 11 22 33 44 55 65 73
mksh            : 11 22 33 44 55 65 73
ksh93           : 11 22 33 44 55 65 73
attsh           : 11 22 33 44 55 65 73
zsh/ksh         : 11 22 33 44 55 65 73

Это не удается для zsh (не в эмуляции )как потому, что zsh не разбивается по умолчанию, так и потому, что нумерация массива начинается с 1 (, а не с 0 ). Это было проверено в csh и tcsh, но это не работает.
И это не предполагается там работать (не используйте csh для скриптов! ).

Решения, работающие снизу вверх, должны легко создаваться с помощью tac на входе.

2
27.01.2020, 20:20

Теги

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