Bash: 행을 배열 요소로 변환

Bash: 행을 배열 요소로 변환

내 macOS 시스템에는 다음 형식의 log.txt가 있습니다.

#State:      a           b        c
State 1:118.851979 120.668604 84.472229
State 2:126.789728 149.506520 103.196917
State 3:126.379687 149.382354 104.504792
State 4:126.989312 149.372811 103.499396
State 5:126.330563 149.373374 103.956438
State 6:127.238791 149.458749 103.198541
State 7:125.263833 132.658750 88.320687
State 8:126.828000 148.570000 98.722229
State 9:125.042667 147.087896 98.871813
State 10:124.392521 148.656792 103.744938
State 11:115.969084 131.787022 91.721250
State 12:125.385521 135.633751 91.044167
State 13:125.046354 149.432500 104.132167
State 14:126.368354 149.454480 103.942208
State 15:126.454229 149.583730 104.462458
State 16:114.102083 134.422916 93.555625
State 17:127.905604 138.012417 85.556396
State 18:126.362271 149.187688 104.087229
State 19:115.580250 133.450563 93.011062
State 20:125.555854 133.653730 88.441501

다음과 같은 Python과 같은 배열 형식으로 변환하는 선형 솔루션이 필요합니다.

[[118.851979, 120.668604, 84.472229],[126.789728, 149.506520, 103.196917]...[125.555854, 133.653730, 88.441501]]

그래서 각 행(2,3,4열)에서 3개의 숫자를 모두 가져와 [] 요소에 배열했습니다.

[[a, b, c],[a, b, c],[a, b, c]..[a, b , c]]

답변1

떨어져 awk있는:

$ awk -F'[ :]' 'BEGIN{printf "["}NR>1{printf "[%s,%s,%s],",$3,$4,$5}END{printf "]\n"}' file | sed 's/,\]$/]/'
[[118.851979,120.668604,84.472229],[126.789728,149.506520,103.196917],[126.379687,149.382354,104.504792],[126.989312,149.372811,103.499396],[126.330563,149.373374,103.956438],[127.238791,149.458749,103.198541],[125.263833,132.658750,88.320687],[126.828000,148.570000,98.722229],[125.042667,147.087896,98.871813],[124.392521,148.656792,103.744938],[115.969084,131.787022,91.721250],[125.385521,135.633751,91.044167],[125.046354,149.432500,104.132167],[126.368354,149.454480,103.942208],[126.454229,149.583730,104.462458],[114.102083,134.422916,93.555625],[127.905604,138.012417,85.556396],[126.362271,149.187688,104.087229],[115.580250,133.450563,93.011062],[125.555854,133.653730,88.441501]]

또는 더 명확하게 말하자면:

awk -F'[ :]' 'BEGIN{
                printf "["
              }
              NR>1{
                printf "[%s,%s,%s],",$3,$4,$5
              }
              END{
                printf "]\n"
              }' file | sed 's/,\]$/]/'

설명하다

  • awk -F'[ :]': awk의 입력 필드 구분 기호를 공백 또는 :.
  • BEGIN{printf "["}: 시작 부분을 인쇄합니다 [.
  • NR>1{printf "[%s,%s,%s],",$3,$4,$5}: 첫 번째 줄을 제외한 각 줄에 대해 a 내의 세 번째, 네 번째, 다섯 번째 필드를 [ ]쉼표로 구분하여 인쇄합니다.
  • END{printf "]\n"}: 결론을 인쇄합니다 ].
  • sed 's/,\]$/]/',: END 블록 이전에 마지막으로 추가된 내용을 제거합니다.

답변2

jq배열 배열을 사용하여 데이터를 JSON으로 형식화 할 수 있습니다 .

jq -nRc '[inputs | split(":")] | .[1:] | map(.[1] | split(" ") | map(tonumber))' <log.txt

반올림 된 값을 원하면 바꿀 수 있습니다

map(tonumber)

그리고

map(tonumber | . *1000 | round | . /1000)

$ jq -nRc '[inputs | split(":")] | .[1:] | map(.[1] | split(" ") | map(tonumber | .*1000 |
round | ./1000))' <log.txt
[[118.852,120.669,84.472],[126.79,149.507,103.197],[126.38,149.382,104.505],[126.989,149.373,103.499],[126.331,149.373,103.956],[127.239,149.459,103.199],[125.264,132.659,88.321],[126.828,148.57,98.722],[125.043,147.088,98.872],[124.393,148.657,103.745],[115.969,131.787,91.721],[125.386,135.634,91.044],[125.046,149.433,104.132],[126.368,149.454,103.942],[126.454,149.584,104.462],[114.102,134.423,93.556],[127.906,138.012,85.556],[126.362,149.188,104.087],[115.58,133.451,93.011],[125.556,133.654,88.442]]

답변3

그래서... 이 두 가지 답변 모두 훌륭하지만 정말 긴장됩니다. 설명하겠습니다.

awk"유닉스"로서 말이죠. 그러나 당신이 알고 있다고 가정하는 것은 현명하지 않습니다.어느"awk"라는 말을 듣게 됩니다. 이 모두는 매우 강력하지만 원래 awk에 대한 확장과 매우 ​​호환되지 않습니다(실제로, 그것을 얻는 것이 가능하지만 Mac에서만 가능합니다. 또는 gawk, mawk, nawk auk... 또는 Perl 중 하나입니다. 몇가지 말하자면.

AWK 자체도 완전히 Turing-complete 언어이지만 쉘 명령 언어("bash"라고 함)와 약간 너무 유사하며 저는 이와 같은 인라인을 호출하는 것을 별로 좋아하지 않습니다. 하나의 잘못 배치된 작은따옴표와 갑자기 AWK 명령이 셸에서 실행되지만 완전히 다른 작업을 수행합니다. 좀 무겁기도 하고 뭔가회의이와 같은 비교적 간단한 작업... AWK는 기본적으로 중첩된 연관 배열을 수행할 수 있으며 기본 32비트 부동 소수점 숫자에서 수행할 수 있는 기본 삼각 함수를 가지고 있습니다. Python이 필요하지 않습니다.

해결책 jq놀라운jq...나는 바보처럼 느껴졌습니다. 내가 할 수 있는 일이 전혀 없었습니다.읽다읽을 수 있는 기본 JSON나가...하지만 물론! 나는 무엇을 모른다jq 할 수 없다...최근에 동일한 표기법을 사용하여 XML Xpath를 쉽고 안전하게 처리한 다음 키-값이 반대인 YAML 형식으로 동일한 데이터를 반환할 수 있는 래퍼를 사용했는데 이름이 무엇인지 기억이 나지 않습니다. 놀라운. 그러나 jq이는 기본적으로JSON— (Douglas Crockford가 발명한 데이터 직렬화 형식), 이것도 좋지 않은 것 같습니다.정확히당신이 찾고 있는 것과 같습니다: 1. 비슷해 보이지만 Python 데이터 구조는아니요JSON, Python에서 JSON을 안전하게 처리하려면 이 json모듈을 사용하여 역직렬화가 올바르게 처리되도록 해야 합니다. 등. 이와 같이 JSON에서 중첩된 괄호는 [[],]Python에서와는 완전히 다른 의미를 갖습니다. 이는 JavaScript에서 명시적으로 표현하는 방법입니다.목적댓글 "이건구체적으로대신에 중첩된 배열이 있는 배열물체{}, 대괄호 대신 중괄호 를 사용하세요 []. 예를 들어, 마지막 중첩 배열 뒤에 매달린 쉼표도 처리하지 않습니다. Python은 일반적으로 처리합니다.

만약 이 질문이텍스트 처리, 라벨이 붙은 대로 제가 지적하는 부분은 바로 그 부분입니다.거의 모든최신 쉘은 단일 외부 프로그램을 호출하지 않고도 이러한 유형의 텍스트 처리를 수행할 수 있습니다. 단일 변수(종종 전통적으로 호출되는 루프에서 사용됨 ) 를 인수 read로 사용하는 내장 함수 에 파일을 파이프한 다음 do 블록에서는 각 행을 함수에 매개변수로 전달하여 필드 분할할 수 있습니다. 그러면 이를 특수 변수 및 해당 구성 요소 로 처리합니다 . , ... 등. 필드 분할을 원하지 않으면 를 사용할 수 있습니다 . 실제로 이것은 (일반적으로) 쉘이 갖는 유일한 복잡한 데이터 유형이며 (기본) 산술을 제외하고는 아무것도 숫자로 취급하지 않습니다. 확장은 외부 또는 도구 또는 확장을 호출하여 처럼 보입니다 .whilelinewhile read line < file; do$@$1$2$3$*$(($x + 4))

하지만 그건 아닌 것 같아당신이 묻는 질문은 위의 가장 좋은 "답변"은 @thanasisp의 것입니다. 저는 "이것이 Python에서 사용된다면 그냥 Python을 사용하는 것이 어떻습니까?"라고 해석합니다. "파이썬과 같은 배열 형식"이란 무엇입니까?

우선, "파이썬과 유사한 배열 형식"이라는 문구는 다소 의미가 없습니다. 중첩된 괄호와 쉼표 형식은 느슨하게 호출할 수 있지만-좋다(그것이 나온 언어이고 Python, JSON 및 기타 여러 언어에 존재하는 이유), 각 언어(또는 직렬화 형식)에는 구현 시 미묘하지만 매우 중요한 차이점이 많이 있습니다. 게다가 Python 외에 "Python과 유사한" 언어나 언어 기능은 없습니다. Python은 또한 "quite"라고도 불리는 유일한 언어입니다.같지 않은Python은 Python과 완전히 호환되지 않기 때문에 오늘날 대부분 금지/강제 사용 중단된 "Python 2"를 의미하는지 아니면 원래 Python 3000으로 알려진 포크였던 현재 "Python"을 의미하는지에 따라 다릅니다. , Py3k, Python3이지만 (수년간의 열띤 논쟁 끝에) "Python"이 일반적으로 의미하는 바가 되었습니다.

결론은 모든 버전의 Python에서 완벽하게 유효한 데이터(예: "1:118.851979")를 지정한다는 것입니다. 이는 완벽하게 유효한 구성이지만... 제가 생각하는 대로 작동하지 않습니다. 콜론은 " 슬라이스" 연산자. 그러나 Python에서는 다른 구조적 변수 할당과 마찬가지로 암시적으로 연산을 인라인하는 것이 완벽하게 허용되는 경우가 많으며 다른 곳에서도 코드를 인라인하는 것이 가능한 경우가 많습니다. 그러나 다른 언어에서는 이는 숫자의 비율로 해석될 수 있습니다. 일부(C++ 등)에서는 콜론이 개체 또는 템플릿 선택기를 나타내며 셸에서는 null 함수입니다. 또한 귀하가 인용한 예는 완전히 타당하지만, 다시 한 번 제가 가정했던 것과는 완전히 다른 것을 의미한다고 믿습니다.실제로평균 - [[a, b, c],[a, b, c],[a, b, c]...이전에 정의된 세 개의 변수("a", "b" 또는 "c"로 명명)에 대한 참조와 동일한 변수에 대한 두 개의 연속 참조로 구성된 구조입니다.그게 무슨 뜻이야?

당신이 가지고 있는 예가 고려될 수 있다는 것을 알고 있지만 실제로는 그렇습니다.

관련 정보