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.