쉘 변수를 사용하여 한 필드를 다른 필드로 바꾸는 방법은 무엇입니까?

쉘 변수를 사용하여 한 필드를 다른 필드로 바꾸는 방법은 무엇입니까?

다음 코드를 고려해보세요.

renamed_column='2
6
10
8
22
20
6-
18
8-
12
16'

array1='2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6 0.00000 -0.93906
18 0.07618 -0.86288
8 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389'

명령을 사용하여 첫 번째 필드를 바꾸고 싶습니다 $1.array1renamed_columnawk

내 시도는 사용법을 기반으로 했지만 awk -v v="$renamed_column" '{$1=v; print $0}' <<< "$array1"작동하지 않습니다.

원하는 출력은 다음과 같습니다.

2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389

답변1

$ awk -v v="$renamed_column" 'BEGIN{split(v,r)} {$1=r[NR]} 1' <<<"$array1"
2 0.00000 -1.45191
6 0.81778 -0.63413
10 0.85020 -0.60170
8 1.40260 -0.04931
22 3.25781 1.80590
20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711
16 0.88517 -0.05389

물론 이 작업을 수행하는 다른 방법도 많이 있습니다. 위의 내용은 원래 명령을 최소한으로 변경하여 수행하는 방법을 보여줍니다.

위의 내용은 쉘 스칼라 변수의 내용을 renamed_columnawk 스칼라 변수에 저장 v한 다음 내용을 vawk 배열로 분할한 다음 각 첫 번째 필드(from)의 값을 변경하여 행별로 입력하여 현재 행 r에 의해 인덱스된 <<<"$array1"내용을 추가합니다. r[]번호는 에 저장됩니다 NR.

답변2

array1.txt두 개의 파일과 그 안에 데이터가 있는 경우 renamed_column.txt다음을 수행할 수 있습니다.

awk -v replfile=renamed_column.txt '{getline x < replfile; $1 = x; print; }' array1.txt  > output.txt

예를 들어 renamed_column.txt입력 데이터라면 살짝 줄여서 입력하세요.

20
6-
18
8-
12

그리고 array1.txt그에 상응하는

20 4.32051 2.86860
6 0.00000 -0.93906
18 0.07618 -0.86288
8 0.36922 -0.56984
12 0.71195 -0.22711

그러면 결과 output.txt

20 4.32051 2.86860
6- 0.00000 -0.93906
18 0.07618 -0.86288
8- 0.36922 -0.56984
12 0.71195 -0.22711

이와 같은 셸 변수에 데이터가 있고 그런 식으로 유지해야 하는 경우 Bash/ksh/zsh에서 프로세스 대체를 사용하여 데이터를 awk로 파이프할 수 있습니다.

awk -v replfile=<(echo "$renamed_column") '{getline x < replfile; $1 = x; print; }' <(echo "$array1")

그러나 awk를 사용할 계획이라면 파일의 데이터를 처리하는 것이 더 쉬울 것입니다.

답변3

~에 따르면이 답변에 대한 댓글, 데이터는 질문과 같이 공백으로 구분되지 않고 탭으로 구분됩니다. 이를 염두에 두고 아래 코드를 수정했습니다.

paste대신 사용 하고 있는 쉘이 여기에서 문자열 리디렉션을 지원한다고 가정 하고 cut다음 을 사용하십시오 .awk<<<"..."<(...)

paste - <( cut -f 2- <<<"$array1" ) <<<"$renamed_column"

paste이는 두 개의 탭으로 구분된 필드를 생성하고 유틸리티의 표준 입력에서 읽은 임시 파일을 만드는 데 사용됩니다 .

표준 입력( -명령줄에서 자리 표시자로 표시됨 paste)은 문자열 입력이 리디렉션되는 첫 번째 필드입니다 $renamed_column.

임시 파일은 프로세스 교체를 통해 동적으로 생성되며 에서 처리되는 두 번째 필드를 제공합니다 paste. cut문자열에서 첫 번째 탭으로 구분된 필드를 제외한 모든 필드를 추출 $array1하고 다른 here 문자열을 통해 해당 문자열을 읽는 프로세스 교체가 실행됩니다 .

데이터가 파일에 있는 경우 위의 문자열 리디렉션을 파일 이름으로 바꾸세요.

paste new_column_1 <( cut -f 2- old_data )

관련 정보