"column -t"가 특정 특성을 가진 행을 무시하도록 만드는 방법은 무엇입니까?

"column -t"가 특정 특성을 가진 행을 무시하도록 만드는 방법은 무엇입니까?

/etc/fstabcolumn -te나는 파이프를 통해 멋진 형식의 테이블을 얻는 것이 얼마나 좋을지 생각했습니다 .
그러나 column물론 주석 행과 마운트 지점 정의는 인식되지 않으므로 주석도 모든 공간에서 분할되고 테이블 열 형식으로 지정됩니다.

#                                          /etc/fstab:                  static   file                                      system     information.
#
#                                          Use                          'blkid'  to                                        print      the           universally   unique      identifier  for       a
#                                          device;                      this     may                                       be         used          with          UUID=       as          a         more  robust     way  to  name  devices
#                                          that                         works    even                                      if         disks         are           added       and         removed.  See   fstab(5).
#
#                                          <file                        system>  <mount                                    point>     <type>        <options>     <dump>      <pass>

#                                          /                            was      on                                        /dev/sda2  during        installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /                            btrfs    defaults,subvol=@rootfs,metadata_ratio=6  0          1
#                                          /home                        was      on                                        /dev/sda2  during        installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /home                        btrfs    defaults,subvol=@home                     0          2

column로 시작하지 않는 형식 줄만 만드는 방법이 있나요 #?


fstab편집: 위의 예가 실제로 Btrfs 에 유효한 것임을 명확히 해야 할 것 같습니다 .하위 볼륨subvol및 설치 옵션을 사용하여 별도로 설치할 수 있습니다 subvolid.
이는 또한 첫 번째 열의 장치가 fstab반드시 고유할 필요는 없음을 의미합니다.

답변1

내 생각에 실용적인 해결책은 column전체 파일이 작동하도록 하고 주석 줄의 여러 공백을 간단히 축소하는 것입니다.

column -t /etc/fstab | sed '/^#/ s/ \{1,\}/ /g'

그렇지 않으면 줄에 번호를 매기고 주석 줄과 주석이 아닌 줄을 별도로 처리한 다음 모두 함께 붙이는 것 외에는 이 작업을 수행할 수 있는 방법이 없습니다.

sort -nk1,1 \
<(nl -nln /etc/fstab | grep -vE '^[[:digit:]]+[[:space:]]+#'| column -t | sed 's/ \{1,\}/\t/') \
<(nl -nln /etc/fstab | grep -E '^[[:digit:]]+[[:space:]]+#') \
| cut -f2-

답변2

그리고 :sednl

nl -ba -nrz -s: /etc/fstab | \
sed '/^[[:digit:]]*:[[:blank:]]*\(#\|$\)/d;//!{s/\\/&&/g}' | \
column -t | sed 's|^0*\([[:digit:]]*\):\(.\)|\1c\\\
\2|' | sed -f - /etc/fstab

또는 sedgrep:

grep -nvE '^[[:blank:]]*(#|$)' /etc/fstab | \
sed -E 's/\\/&&/g;s/^([[:digit:]])*:(.*)/\1c\\\
\2/' | column -t | sed -f - /etc/fstab

또는 더 짧게, sed다음을 사용 awk:

awk '!/^[[:blank:]]*(#|$)/{print NR"c\\";gsub(/\\/,"&&");print}' \
/etc/fstab | column -t | sed -f - /etc/fstab

테스트 파일 사용:

# /etc/fstab: static file system information
# <file system> <dir>   <type>  <options>   <dump>  <pass>

LABEL=ROOT    / ext4 noatime,discard 0 1
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  / btrfs  defaults,subvol=@rootfs,metadata_ratio=6 0  1
# /home was on /dev/sda2  during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /home btrfs  defaults,subvol=@home  0 2
LABEL=SWAP   none  swap sw,discard  0 0
UUID=7fa3-cb08  /media ext4 defaults 0 0

출력은 다음과 같습니다

# /etc/fstab: static file system information
# <file system> <dir>   <type>  <options>   <dump>  <pass>

LABEL=ROOT                                 /       ext4   noatime,discard                           0  1
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /       btrfs  defaults,subvol=@rootfs,metadata_ratio=6  0  1
# /home was on /dev/sda2  during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /home   btrfs  defaults,subvol=@home                     0  2
LABEL=SWAP                                 none    swap   sw,discard                                0  0
UUID=7fa3-cb08                             /media  ext4   defaults                                  0  0

작동 방식:
마지막 명령은 이전 명령으로 생성된 스크립트 파일을 사용하고(읽기) sed -f - /etc/fstab마운트 지점 정의만 수정합니다 /etc/fstab(빈 줄을 포함하여 다른 줄은 변경하지 않음).f-stdin

4c\
LABEL=ROOT                                 /       ext4   noatime,discard                           0  1
5c\
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /       btrfs  defaults,subvol=@rootfs,metadata_ratio=6  0  1
7c\
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /home   btrfs  defaults,subvol=@home                     0  2
8c\
LABEL=SWAP                                 none    swap   sw,discard                                0  0
9c\
UUID=7fa3-cb08                             /media  ext4   defaults                                  0  0

첫 번째는 nl -ba -nrz -s:모든 행에 번호를 매기 는 데 사용됩니다.

sed '/^[[:digit:]]*:[[:blank:]]*\(#\|$\)/d;//!{s/\\/&&/g}'

column -t처음에 주석 처리된 줄이나 빈 줄을 제거하고 나머지 줄에서 백슬래시를 모두 이스케이프 처리한 다음(이 특별한 경우에는 필요하지 않은 것으로 알고 있음) 마운트 지점 정의만 나열되도록 출력을 파이프합니다 .

000004:LABEL=ROOT                                 /       ext4   noatime,discard                           0  1
000005:UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /       btrfs  defaults,subvol=@rootfs,metadata_ratio=6  0  1
000007:UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /home   btrfs  defaults,subvol=@home                     0  2
000008:LABEL=SWAP                                 none    swap   sw,discard                                0  0
000009:UUID=7fa3-cb08                             /media  ext4   defaults                                  0  0

이는 추가 처리됩니다.

sed 's|^0*\([[:digit:]]*\):\(.\)|\1c\\\
\2|'

위 스크립트 파일을 생성합니다.
두 번째와 세 번째는 비슷합니다(동일한 출력을 생성함).

grep -nvE '^[[:blank:]]*(#|$)' | sed -E 's/\\/&&/g;s/^([[:digit:]])*:(.*)/\1c\\\
\2/'

또는

awk '!/^[[:blank:]]*(#|$)/{print NR"c\\";gsub(/\\/,"&&");print}'

마운트 지점 정의만 일치하고, 백슬래시(있는 경우)를 이스케이프 처리하고, 줄 번호와 c\실제 줄 내용을 인쇄합니다(별도의 줄에).

4c\
LABEL=ROOT    / ext4 noatime,discard 0 1
5c\
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  / btrfs  defaults,subvol=@rootfs,metadata_ratio=6 0  1
7c\
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /home btrfs  defaults,subvol=@home  0 2
8c\
LABEL=SWAP   none  swap sw,discard  0 0
9c\
UUID=7fa3-cb08  /media ext4 defaults 0 0

그런 다음 파이프를 통해 column -t동일한 스크립트 파일을 생성합니다.


다른 방법도 ed동일하지만 파일을 한 번만 읽습니다.

ed -s <<IN <(nl -ba -nrz -s: /etc/fstab) | sort -t: -k1,1 | cut -d: -f2-
g/^[[:digit:]]*:[[:blank:]]*\(#\|$\)/p
g//d
,w !column -t
q
IN

번호가 매겨진 줄은 입력으로 사용되며 ed, 첫 번째 하위 명령은 p처음에 주석 처리된 줄이나 빈 줄( g)을 모두 인쇄하고, 두 번째 하위 명령은 d이를 제거한 다음 나머지 줄을 입력( )으로 wshell( !) 명령 에 전달합니다 column -t. 전체 출력이 sort편집되고 cut선행 숫자가 제거됩니다.

답변3

"리뷰를 제출하기 전에 삭제하는 것이 어떻습니까?"라는 제안이 column전혀 가치가 없는 것은 아닙니다.

#!/bin/sh
nl -ba /etc/fstab | sed "s/^ *//; s/\t/ /" > file0
grep    "^[0-9][0-9]* #" file0 > file1
grep -v "^[0-9][0-9]* #" file0 > file2
(cat file1; column -t file2) | sort -n | sed "s/^[0-9][0-9]* *//"

nl –ba각 줄에는 번호가 매겨져 있습니다. %6d\t즉, 숫자 앞에 공백이 있고 그 뒤에 탭 문자가 옵니다.  선행 공백을 제거하고 탭 문자를 공백으로 대체하여 출력 sed "s/^ *//; s/\t/ /"과 더 유사하게 만듭니다 . 명령 column은 주석 처리된 줄과 주석 처리되지 않은 줄로 grep구분됩니다 . ( 방법file0file1file2XX*X0개 이상의 Xs, 즉 하나 이상의 Xs가 옵니다. 이는 "가난한 사람의 버전"입니다 X+. 즉, 하나 이상의 s를 이식 가능/일반적인 방식으로 표현하는 방법입니다 X. ) 각 파일은 줄 번호를 유지합니다원본 /etc/fstab파일 에서.

(cat file1; column -t file2)주석 처리되지 않은 행을 실행하여 column –t결과를 주석 처리된 행(수평 간격이 수정되지 않음)에 연결합니다 . 그런 다음 sort –n줄을 원래 순서로 복원하고 sed "s/^[0-9][0-9]* *//"줄 번호를 제거합니다.

산출:

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>

# / was on /dev/sda2 during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /      btrfs  defaults,subvol=@rootfs,metadata_ratio=6  0  1
# /home was on /dev/sda2 during installation
UUID=8fa99d69-8dac-4aca-bb61-90f753ba5169  /home  btrfs  defaults,subvol=@home                     0  2

이는 빈 줄과 공백이 포함된 주석 줄(즉, 탭 또는 두 개 이상의 공백이 포함된 문자열)을 지원하지만 들여쓰기된 줄(예:선두탭 또는 공백).

이 스크립트를 약간 강화하려는 경우(즉, 프로덕션 버전과 더 유사하게 만들기) 다음을 수행할 수 있습니다.

  • 임시 파일을 /tmp임의로( mktemp) 생성된 이름을 가진 파일로 바꾸십시오.
  • 완료되면 임시 파일을 삭제합니다.
  • 적절한 경우 사용하도록 변경하십시오 [0-9]+(시스템이 너무 오래된 경우(예: Solaris, AIX 또는 GNU 도구가 없는 시스템)에는 적용되지 않을 수 있습니다).
  • file1and를 삭제 file2하고 마지막 줄을 다음과 같이 압축합니다.

    (grep "^[0-9][0-9]* #" file0; grep -v "^[0-9][0-9]* #" file0 | column -t) | …
    

    하지만 몇 줄 더 써서 좀 더 명확하게 작성하는 것이 좋을 것 같습니다.

  • 들여쓰기된 줄에 대한 지원을 추가합니다.

답변4

컬럼만으로는 이 작업을 수행할 수 없을 것 같습니다. 이를 수행하기 위한 간단한 스크립트를 작성하는 것은 그리 어렵지 않을 것입니다.

편집: 이것은 작동할 수도 있고 조금 더 짧을 수도 있습니다. 열을 통과했지만 위의 원래 예에서 시도했습니다. 나는 이것이 빈 줄을 제거한다는 것을 알았으므로 그것이 문제라면 여전히 약간의 다듬기가 필요할 수 있습니다.

#!/bin/bash

INPUTFILE="${1}"

IFS=$'\r\n' GLOBIGNORE='*';
COMMENTS=(`grep -n ^# "${INPUTFILE}"`) 
ENTRIES=(`grep -n -v ^# "${INPUTFILE}" | column -t`)
TMPTAB=(`printf "%s\n" ${ENTRIES[@]} && printf "%s\n" ${COMMENTS[@]}`)

NEWTAB=(`printf "%s\n" ${TMPTAB[@]} | sort -n -t: -k1 | sed 's/^[0-9]\+://'`)
printf "%s\n" ${NEWTAB[@]}

여기에 원래 답변을 남겨 두겠지만 @scott이 지적했듯이 일부 유효한 fstab에서는 작동하지 않습니다.

#!/bin/bash 

# columnize the non-comment lines
TABS=`grep -v ^# /etc/fstab | column -te`

# read the original fstab
while read LINE
 do 
  echo "${LINE}" | grep ^# > /dev/null 

  # if it is a comment line just write it in
  if [ $? -eq 0 ]
  then
       echo "${LINE}" >> new.fstab
  else
    # otherwise get the matching entry from the columnized fstab 
    ENTRY=`echo "${LINE}" | awk '{ print $1 }'`
    echo "${TABS}" | grep ^"${ENTRY}" >> new.fstab
  fi
 done < /etc/fstab

관련 정보