시작 키 토큰과 n개의 토큰이 주어지면 n개의 토큰을 키와 인터리브합니다.

시작 키 토큰과 n개의 토큰이 주어지면 n개의 토큰을 키와 인터리브합니다.

osx 셸에서 이러한 줄이 포함된 스트림이 주어지면 첫 번째 토큰이 키이고 줄의 첫 번째 문자가 항상 일치하며 [a-z]나머지 토큰은 항상 숫자일 뿐이며 해당 숫자는 가변적이며 단일 공백만 구분합니다. 토큰:

key  [1] [...] [n]
---- --------------------
key1 17 89 52
key2 5 189 6 3 5 21

교체를 반복해서 수행하지 않고 어떻게 다음 출력(각 줄의 토큰 수와 무관)을 내보낼 수 있나요?

17 key1
89 key1
52 key1
5 key2
189 key2
6 key2
3 key2
5 key2
21 key2

(키와 숫자를 바꾸거나 각 줄을 공백으로 구분하는 대신 개행 문자를 사용하세요 key1 17 key1 89 key1 52. 토큰을 바꾸거나 여러 줄로 쉽게 나눌 수 있기 때문입니다.)

현재 sed키가 없는 다음 번호마다 연속 교체를 사용하고 있지만 이는 비효율적이며 최대 토큰 수보다 더 많은 횟수를 파이프해야 하므로 sed증가할 수 있습니다(그렇지 않으면 여기에 있을 이유를 추측합니다). ?):

sed -E 's/^([a-z][^ ]*) ([0-9]+) /\2 \1\n\1 /g' filename.txt | sed ... | sed ...

내가 그것에 대해 파헤쳐 볼 시간이 있다면 awk이것이 효과가 있을 것이라고 확신합니다. 아마도 cut작업을 수행하거나 토큰을 효율적으로 사용할 수 있는 다른 도구 중 하나일 수 있습니다.

코드 및 처리 시간 측면에서 이를 효율적으로 수행하려면 어떻게 해야 합니까?

답변1

이를 달성하기 위해 awk를 사용할 수 있습니다

awk '{ for(i = 2; i <= NF; i++) { print $i,$1; } }'  file

for 루프는 두 번째 필드에서 마지막 필드로 이동하여 각 필드를 인쇄하고 첫 번째 필드를 추가합니다.

답변2

sed이 작업에 적합합니다. sed 코드를 약간만 조정하면 다음과 같은 결과를 얻을 수 있습니다.

sed -E '
    s/^([a-z][^ ]*) ([0-9]+)/\2 \1\n\1/
    /\n/P;D
' filename.txt

산출:

17 key1
89 key1
52 key1
5 key2
189 key2
6 key2
3 key2
5 key2
21 key2

설명하다:

  • 당신은 내가 당신에게서 받은 대체 s/// 명령을 이미 알고 있습니다 global /g flag. .
  • 기본 아이디어는 처음 두 요소를 보고 뒤집기 전에 첫 번째 요소의 복사본을 저장하고(뒤집기 전) 뒤집기 작업 후에 개행 문자를 입력하여 패턴 공간에서 까지 인쇄하는 명령을 \n사용할 수 있도록 하는 것입니다. P첫 번째 개행 문자.
  • P/\n/무한 루프를 방지하려면 a로 정의하세요 .
  • D패턴 공간의 첫 번째 개행 문자와 패턴 공간의 나머지 부분을 제거하여 제어권을 스크립트의 맨 위로 다시 가져옵니다. IOW, 당신이 하고 있는 일은 암시적 루핑 메커니즘을 제공하는 것입니다.
  • 현재 행의 루프는 패턴 공간이 결국 연속적인 프로세스에 의해 소모될 때 종료됩니다 s/// --- P --- D --- s/// --- P --- D ............
  • 그 후에 sed새로운 독서 주기를 시작하면 무엇을 기대하게 될지 알 수 있습니다.... HTH.

관련 정보