단어를 파일의 줄 번호 및 위치 번호로 바꿔야 함

단어를 파일의 줄 번호 및 위치 번호로 바꿔야 함

단어를 파일의 줄 및 위치 번호로 바꿔야 합니다.

파일 1에는 다음이 포함됩니다.

ABC XYZ UIO WER GFH
DFG JHKS
WEQ RWT DSW
ANSN WERER WERT QAZX UWRE AA

해당 내용을 다음과 같이 교체해야 합니다.

S_11 S_12 S_13 S_14 S_15
S_21 S_22
S_31 S_32 S_33
S_41 S_42 S_43 S_44 S_45 S_46

그 말은 다시 반복되지 않을 것입니다. 각 파일에는 서로 다른 세트와 단어 수가 있을 수 있습니다.

답변1

perl-에 기반한 또 다른 방법:

perl -pe 'my $i; s{\S+}{"S_$." . ++$i}ge'

S_<line-number><word-number>이는 기존 공백을 유지하면서 각 줄의 ASCII가 아닌 공백 문자의 모든 시퀀스를 대체합니다 .

입력에 ASCII가 아닌 공백 문자가 포함될 수 있는 경우 예를 들면 다음과 같습니다.

U+0085 다음 줄
U+00A0 줄 바꿈 없는 공백
U+1680 OGHAM 공백 표시
U+2000 EN QUAD
U+2001 EM QUAD
U+2002 EN 공백
U+2003 EM 공백
U+2004 공백 세 개마다
U+2005 공백 네 개
U +2006 여섯 공백
U+2007 숫자 공백
U+2008 구두점 공백
U+2009 가는 공백
U+200A 머리털 공백
U+2028 줄 구분자
U+2029 단락 구분자
U+202F 줄바꿈 없는 좁은 공백
U+205F 중급 수학 공백
U+ 3000 표의 문자 공간

사용자의 로케일에 따라 인코딩되며 해당 -Mopen=locale옵션을 추가할 수 있습니다.

"줄바꿈하지 않는" 공백(위의 U+00A0, U+2007 및 U+202F)은 구분 기호로 간주되어서는 안 되므로 제외할 수도 있고 제외하지 않을 수도 있습니다. perlPCRE(포함 (*UCP))에는 이를 포함하지만 GNU 로케일 [:space:] CTYPE범주에는 포함되지 않습니다. 내 시스템에서는 U+0085가 로케일에 포함되어 있지 않고 [:space:]PCRE에도 U+180E 몽골어 모음 구분 기호(여기서)가 포함되어 있음 을 발견했습니다.유니코드에서는 공백으로 분류되었으나 더 이상 분류되지 않습니다.). 캐릭터 perl도 보세요\PZ아니요(대문자 p) 구분자와 \P{Zs}문자 로 분류아니요공백 구분 기호로 분류됩니다(TAB을 포함한 제어 문자는 구분 기호로 간주되지 않음). 나는 이것이 \p{Zs}그 자체의 하위 집합이라는 것을 알았습니다 . \pZ그렇습니다. 하위 집합입니다.\s

답변2

$ perl -lane '$i=1; print join(" ", map { "S_$." . $i++ } @F)' file1
S_11 S_12 S_13 S_14 S_15
S_21 S_22
S_31 S_32 S_33
S_41 S_42 S_43 S_44 S_45 S_46
  • -l줄 끝 자동 처리
  • -a입력 행을 @F라는 배열로 자동 분할
  • -n와 유사하게 아무것도 인쇄하지 않고 각 입력 줄을 반복합니다 sed -n.
  • -e다음 매개변수는 실행할 스크립트입니다.

각 행은 (공백에서) 자동으로 배열로 분할됩니다 ( 각 입력 행이 자동으로 $1, $2, ..., $NF로 분할되는 @F방식과 유사 ).awk

스크립트는 $i각 입력 줄의 시작 부분에서 1로 재설정됩니다.

map이 함수는 @F의 각 요소에 대해 하나의 요소가 있는 리터럴 문자열, 줄 번호( ) 및 변수(사용할 때마다 $i 증분)로 구성된 문자열 목록을 반환합니다 .S_$.$i++

그런 다음 목록의 각 요소가 공백으로 연결되어 인쇄됩니다.

출력은 표준 출력으로 이동합니다. 입력 파일을 변경하려면 -iperl사이에 옵션을 추가하십시오 -l. 또는 -i.bak덮어쓰기 전에 원본 파일을 백업하려는 경우에도 가능합니다.


그런데 출력에서 ​​줄 번호($.)와 단어 카운터($i) 사이에 구분 기호가 없기 때문에 첫 번째 줄의 11번째 단어("S_111")와 첫 번째 줄을 구별할 수 있는 방법이 없습니다. 단어("S_111"이라고도 함). .두 값 사이에 구분 기호(예: 또는 다른 것)를 추가하는 것이 좋습니다 . _또한 숫자는 항상 같은 자릿수를 갖도록 0으로 채워질 수 있습니다. 예를 들어, sprintf()내부 함수를 사용하십시오 map.

$ perl -lane '$i=1; print join(" ", map { sprintf "S_%03i.%03i", $., $i++ } @F)' file1
S_001.001 S_001.002 S_001.003 S_001.004 S_001.005
S_002.001 S_002.002
S_003.001 S_003.002 S_003.003
S_004.001 S_004.002 S_004.003 S_004.004 S_004.005 S_004.006

답변3

S_1234예를 들어, 주어진 출력이 12행의 34열이나 123행의 4열 또는 다른 것을 의미하는지 어떻게 알 수 있습니까 ? _출력에서 행과 열 번호 사이에 구분 기호를 사용하지 않는 것은 다음에 이 데이터로 수행할 작업에 대해 나쁜 생각처럼 보입니다.

이렇게 하면 귀하가 요청한 작업이 수행됩니다.

$ awk '{for (i=1; i<=NF; i++) $i="S_" NR i} 1' file
S_11 S_12 S_13 S_14 S_15
S_21 S_22
S_31 S_32 S_33
S_41 S_42 S_43 S_44 S_45 S_46

하지만 다음 사항을 고려해보세요.

$ awk '{for (i=1; i<=NF; i++) $i="S_" NR "_" i} 1' file
S_1_1 S_1_2 S_1_3 S_1_4 S_1_5
S_2_1 S_2_2
S_3_1 S_3_2 S_3_3
S_4_1 S_4_2 S_4_3 S_4_4 S_4_5 S_4_6

따라서 출력의 행과 열 번호를 독립적인 값으로 확실하게 구별할 수 있습니다.

위의 코드는 각 줄에서 선행/후행 공백을 제거하고 모든 연속 공백 체인을 단일 공백 ​​문자로 변환합니다. 이것이 문제인지 의심스럽습니다. 만약 문제가 된다면 알려주시기 바랍니다.

답변4

당신은 그것을 사용할 수 있습니다 awk:

awk '{for (i=1; i<=NF; i++){ printf "S_"NR i " " } print ""  }' file1 > newfile
mv newfile file1

또는 다음을 사용하는 경우 (일반적으로 gawkLinux에 awk연결됨 gawk):

gawk -i inplace '{for (i=1; i<=NF; i++){ printf "S_"NR i " " } print ""  }' file1

awk 에서는 for (i=1; i<=NF; i++)행당 총 열 수를 반복하는 데 사용됩니다. NF각 행의 현재 열 수를 저장합니다. awk
의 경우 I를 사용하여 현재 행 번호를 가져오고 이를 사용하여 현재 열 인덱스를 가져옵니다.printf "S_"NR i " "NRi

관련 정보