Bash에서 테이블 열을 정렬하려면 어떻게 해야 합니까?
텍스트 형식을 테이블로 지정합니다.나는 반향을 시도했다.'\t'
세퍼레이터가 잘못 정렬되었습니다.
원하는 출력:
a very long string.......... 112232432 anotherfield
a smaller string 123124343 anotherfield
다음 명령을 사용합니다.
column -t -s' ' filename
printf
대단하지만 사람들은 그걸 잊어버려요.
$ for num in 1 10 100 1000 10000 100000 1000000; do printf "%10s %s\n" $num "foobar"; done
1 foobar
10 foobar
100 foobar
1000 foobar
10000 foobar
100000 foobar
1000000 foobar
$ for((i=0;i<array_size;i++));
do
printf "%10s %10d %10s" stringarray[$i] numberarray[$i] anotherfieldarray[%i]
done
사용한 주의사항%10s
현악기용. %s
중요한 부분이에요.줄을 쓰라고 하네요.그10
가운데에 몇 개의 컬럼이 있는지 보여줍니다. %d
는 숫자(수치)에 대한 것입니다.
상세한 것에 대하여는, 을 참조해 주세요.
function printTable()
{
local -r delimiter="${1}"
local -r data="$(removeEmptyLines "${2}")"
if [[ "${delimiter}" != '' && "$(isEmptyString "${data}")" = 'false' ]]
then
local -r numberOfLines="$(wc -l <<< "${data}")"
if [[ "${numberOfLines}" -gt '0' ]]
then
local table=''
local i=1
for ((i = 1; i <= "${numberOfLines}"; i = i + 1))
do
local line=''
line="$(sed "${i}q;d" <<< "${data}")"
local numberOfColumns='0'
numberOfColumns="$(awk -F "${delimiter}" '{print NF}' <<< "${line}")"
# Add Line Delimiter
if [[ "${i}" -eq '1' ]]
then
table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")"
fi
# Add Header Or Body
table="${table}\n"
local j=1
for ((j = 1; j <= "${numberOfColumns}"; j = j + 1))
do
table="${table}$(printf '#| %s' "$(cut -d "${delimiter}" -f "${j}" <<< "${line}")")"
done
table="${table}#|\n"
# Add Line Delimiter
if [[ "${i}" -eq '1' ]] || [[ "${numberOfLines}" -gt '1' && "${i}" -eq "${numberOfLines}" ]]
then
table="${table}$(printf '%s#+' "$(repeatString '#+' "${numberOfColumns}")")"
fi
done
if [[ "$(isEmptyString "${table}")" = 'false' ]]
then
echo -e "${table}" | column -s '#' -t | awk '/^\+/{gsub(" ", "-", $0)}1'
fi
fi
fi
}
function removeEmptyLines()
{
local -r content="${1}"
echo -e "${content}" | sed '/^\s*$/d'
}
function repeatString()
{
local -r string="${1}"
local -r numberToRepeat="${2}"
if [[ "${string}" != '' && "${numberToRepeat}" =~ ^[1-9][0-9]*$ ]]
then
local -r result="$(printf "%${numberToRepeat}s")"
echo -e "${result// /${string}}"
fi
}
function isEmptyString()
{
local -r string="${1}"
if [[ "$(trimString "${string}")" = '' ]]
then
echo 'true' && return 0
fi
echo 'false' && return 1
}
function trimString()
{
local -r string="${1}"
sed 's,^[[:blank:]]*,,' <<< "${string}" | sed 's,[[:blank:]]*$,,'
}
샘플 실행
$ cat data-1.txt
HEADER 1,HEADER 2,HEADER 3
$ printTable ',' "$(cat data-1.txt)"
+-----------+-----------+-----------+
| HEADER 1 | HEADER 2 | HEADER 3 |
+-----------+-----------+-----------+
$ cat data-2.txt
HEADER 1,HEADER 2,HEADER 3
data 1,data 2,data 3
$ printTable ',' "$(cat data-2.txt)"
+-----------+-----------+-----------+
| HEADER 1 | HEADER 2 | HEADER 3 |
+-----------+-----------+-----------+
| data 1 | data 2 | data 3 |
+-----------+-----------+-----------+
$ cat data-3.txt
HEADER 1,HEADER 2,HEADER 3
data 1,data 2,data 3
data 4,data 5,data 6
$ printTable ',' "$(cat data-3.txt)"
+-----------+-----------+-----------+
| HEADER 1 | HEADER 2 | HEADER 3 |
+-----------+-----------+-----------+
| data 1 | data 2 | data 3 |
| data 4 | data 5 | data 6 |
+-----------+-----------+-----------+
$ cat data-4.txt
HEADER
data
$ printTable ',' "$(cat data-4.txt)"
+---------+
| HEADER |
+---------+
| data |
+---------+
$ cat data-5.txt
HEADER
data 1
data 2
$ printTable ',' "$(cat data-5.txt)"
+---------+
| HEADER |
+---------+
| data 1 |
| data 2 |
+---------+
REF LIB: https://github.com/gdbtek/linux-cookbooks/blob/master/libraries/util.bash
필요한 출력과 동일한 출력을 얻으려면 파일을 다음과 같이 포맷해야 합니다.
a very long string..........\t 112232432\t anotherfield\n
a smaller string\t 123124343\t anotherfield\n
다음으로 다음을 사용합니다.
$ column -t -s $'\t' FILE
a very long string.......... 112232432 anotherfield
a smaller string 123124343 anotherfield
생각보다 쉬워요.
semicolon 파일 및 헤더를 구분하여 작업하는 경우:
$ (head -n1 file.csv && sort file.csv | grep -v <header>) | column -s";" -t
어레이를 사용하는 경우(탭을 구분자로 사용):
for((i=0;i<array_size;i++));
do
echo stringarray[$i] $'\t' numberarray[$i] $'\t' anotherfieldarray[$i] >> tmp_file.csv
done;
cat file.csv | column -t
awk
stdin을 다루는 용액
부터column
POSIX가 아닌 경우:
mycolumn() (
file="${1:--}"
if [ "$file" = - ]; then
file="$(mktemp)"
cat > "${file}"
fi
awk '
FNR == 1 { if (NR == FNR) next }
NR == FNR {
for (i = 1; i <= NF; i++) {
l = length($i)
if (w[i] < l)
w[i] = l
}
next
}
{
for (i = 1; i <= NF; i++)
printf "%*s", w[i] + (i > 1 ? 1 : 0), $i
print ""
}
' "$file" "$file"
if [ "$1" = - ]; then
rm "$file"
fi
)
테스트:
printf '12 1234 1
12345678 1 123
1234 123456 123456
' > file
테스트 명령:
mycolumn file
mycolumn <file
mycolumn - <file
전체 출력:
12 1234 1
12345678 1 123
1234 123456 123456
다음 항목도 참조하십시오.
어디서 실행했는지 모르겠지만, 당신이 올린 코드는 적어도 내가 잘 아는 Bash 버전에서는 출력되지 않습니다.
대신 다음을 시도해 보십시오.
stringarray=('test' 'some thing' 'very long long long string' 'blah')
numberarray=(1 22 7777 8888888888)
anotherfieldarray=('other' 'mixed' 456 'data')
array_size=4
for((i=0;i<array_size;i++))
do
echo ${stringarray[$i]} $'\x1d' ${numberarray[$i]} $'\x1d' ${anotherfieldarray[$i]}
done | column -t -s$'\x1d'
이러한 배열을 파일에서 가져올 경우 탭이 포함될 수 있으므로 탭 대신 그룹 구분 문자(0x1D)를 사용합니다.
만약 누군가가 PHP에서 그것을 하고 싶어한다면, 나는 GitHub에 요지를 올렸습니다.
https://gist.github.com/redestructa/2a7691e7f3ae69ec5161220c99e2d1b3
전화만 하면 됩니다.
$output = $tablePrinter->printLinesIntoArray($items, ['title', 'chilProp2']);
7.2 이전 버전의 PHP를 사용하는 경우 코드를 수정해야 할 수 있습니다.
그 후 환경에 따라 에코 또는 writeLine을 호출합니다.
아래 코드는 테스트되었으며 원래 질문에서 요청한 대로 수행합니다.
파라미터:
%30s 30자 열과 텍스트가 오른쪽 정렬됩니다.
%10d 정수 표기법, %10s도 작동합니다.\
stringarray[0]="a very long string.........."
# 28Char (max length for this column)
numberarray[0]=1122324333
# 10digits (max length for this column)
anotherfield[0]="anotherfield"
# 12Char (max length for this column)
stringarray[1]="a smaller string....."
numberarray[1]=123124343
anotherfield[1]="anotherfield"
printf "%30s %10d %13s" "${stringarray[0]}" ${numberarray[0]} "${anotherfield[0]}"
printf "\n"
printf "%30s %10d %13s" "${stringarray[1]}" ${numberarray[1]} "${anotherfield[1]}"
# a var string with spaces has to be quoted
printf "\n Next line will fail \n"
printf "%30s %10d %13s" ${stringarray[0]} ${numberarray[0]} "${anotherfield[0]}"
a very long string.......... 1122324333 anotherfield
a smaller string..... 123124343 anotherfield
column -t
행이 딜리미터 문자로 시작되거나 연속된 딜리미터 문자가 여러 개 있는 경우 빈 필드를 건너뜁니다.
$ printf %s\\n a,b,c a,,c ,b,c|column -s, -t
a b c
a c
b c
따라서 이 awk 함수를 대신 사용합니다(어레이 어레이를 사용하기 때문에 gawk가 필요합니다).
$ tab(){ awk '{if(NF>m)m=NF;for(i=1;i<=NF;i++){a[NR][i]=$i;l=length($i);if(l>b[i])b[i]=l}}END{for(h in a){for(i=1;i<=m;i++)printf("%-"(b[i]+n)"s",a[h][i]);print""}}' n="${2-1}" "${1+FS=$1}"|sed 's/ *$//';}
$ printf %s\\n a,b,c a,,c ,b,c|tab ,
a b c
a c
b c
데이터에 등호가 없는 경우("="
에서, 셸할 수 있습니다.column
것도 면할 수 ...
에 의해
FS
"\t"
)와 임의의 을 값입니다." "
탭 「」( )"\t"
를 각 필드 내에 을 포함할echo "${inputdata2}" |
mawk NF=NF OFS== FS=' + |[ \t]*\t[ \t]*' | column -s= -t
a very long string.......... 112232432 anotherfield
a smaller string 123124343 anotherfield
데이터에 등호가 포함되어 있는 경우 일반적인 데이터에는 존재할 수 없는 콤보 sep을 사용합니다.
gawk -e NF=NF OFS='\301\372\5' FS=' + |[ \t]*\t[ \t]*' | LC_ALL=C column -s$'\301\372\5' -t
a very long string.......... 112232432 anotherfield
a smaller string 123124343 anotherfield
, 첫 의 너비가 으로 알 수 에는 이 필드를 할 수 .\r
화면상의 포맷을 좋게 하기 위한 트릭(단, 파이프에 송신할 필요가 있는 경우는 스페이스의 실행이 되지 않습니다).
# each \t is 8-spaces at console terminal mawk NF=2 FS=' + |[ \t]*\t[ \t]*' OFS='\r\t\t\t\t'
a very long string.......... 112232432
a smaller string 123124343
언급URL : https://stackoverflow.com/questions/12768907/how-can-i-align-the-columns-of-tables-in-bash
'programing' 카테고리의 다른 글
git 마크를 삭제한 파일과 새로운 파일을 파일 이동으로 만드는 방법 (0) | 2023.04.14 |
---|---|
병합된 Git 브랜치를 모두 삭제하려면 어떻게 해야 하나요? (0) | 2023.04.14 |
Windows 콘솔에서 cURL 명령 실행 (0) | 2023.04.14 |
IndexError: 배열에 대한 인덱스가 너무 많습니다. (0) | 2023.04.14 |
stdin은 단말기가 아니기 때문에 의사 단말기는 할당되지 않습니다. (0) | 2023.04.14 |