약 8,000개의 레코드가 포함된 구분된 파일이 있습니다 |
.
3열이 비어 있으면 2열의 값으로 바꾸고 싶습니다. 우리는 이것을 어떻게 달성합니까?
입력하다:
1|100437251|
2|51414204|
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
산출:
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
sed
교체 명령을 사용해 보았습니다 sed -i "s/ /$2/g" input > output
.
답변1
그리고sed:
sed -E 's/^([^|]*\|)([^|]*)\|$/\1\2|\2/' infile
이 부분은 ([^|]*\|)
첫 번째 열과 구분 기호( \1
역참조)를 캡처합니다.
이 부분은 ([^|]*)
두 번째 열( \2
역참조)을 캡처합니다.
이 부분은 \|$
줄 끝인 마지막 구분 기호를 캡처하며 그 뒤에는 다른 구분 기호가 없습니다(세 번째 열이 비어 있음을 의미).
이 부분에서는 \1\2|\2
역참조 주소를 사용하여 첫 번째와 두 번째 열을 반환한 다음 구분 기호를 사용하여 두 번째 열을 다시 복사합니다.
세 번째 열이 비어 있지 않지만 탭/공백( [[:space:]]
)과 같은 공백 문자가 포함될 수도 있는 경우 대신 이 열을 사용하세요.
sed -E 's/^([^|]*\|)([^|]*)\|[[:space:]]*$/\1\2|\2/' infile
그리고앗:
awk 'BEGIN{ FS=OFS="|" } $3 ~/^[[:space:]]*$/ { $3=$2 }1' infile
FS는에프생산하다에스구분 기호, OFS 예산소산출에프생산하다에스그런 다음 세 번째 열이 비어 있는지/탭/공백인지 확인한 다음 해당 내용을 두 번째 열과 동일하게 업데이트합니다. 그런 다음 인쇄하십시오 1
.
답변2
를 사용 awk
하고 세 번째 필드에 공백이 아닌 문자가 포함되어 있지 않은 한 세 번째 필드를 두 번째 필드로 바꿉니다.
$ awk -F '|' 'BEGIN { OFS = FS } $3 !~ /[^[:blank:]]/ { $3 = $2 }; 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
sed
세 번째 필드가 비어 있거나 공백만 포함된 경우 두 번째 필드의 번호를 삽입하는 데 사용됩니다.
$ sed 's/\([[:digit:]]\{1,\}\)|[[:blank:]]*$/\1|\1/' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
세 번째 필드는 다음과 같습니다.언제나두 번째 필드와 마찬가지로 세 번째 필드의 모든 테스트를 무시하고 두 번째 필드의 값이 되도록 강제할 수도 있습니다.
먼저 다음을 사용합니다 awk
.
$ awk -F '|' 'BEGIN { OFS = FS } { $3 = $2 }; 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
심지어
$ awk -F '|' 'BEGIN { OFS = FS } { print NR, $2, $2 }' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
그러면 첫 번째 열도 다시 생성됩니다.
그런 다음 다음을 사용하십시오 sed
.
$ sed 's/|[^|]*$//; s/[[:digit:]]\{1,\}$/&|&/' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
이 sed
명령은 먼저 마지막 필드를 삭제한 다음 삭제된 필드 이전의 필드에서 다시 생성합니다.
아니면 다음과 같은 것
$ cut -d '|' -f 2 file | sed '=; s/.*/&|&/' | sed 'N; y/\n/|/'
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
두 번째 필드를 사용하여 데이터를 추출한 cut
다음 열거 =
에 사용하여 sed
필드의 중복을 연결하고 생성한 다음 마지막으로 올바른 구분 기호를 사용하여 데이터에 행 번호를 추가합니다.
및 (프로세스 대체 사용) 의 조합을 사용하여 셸에서 cut
이 작업을 수행 할 수도 있습니다.paste
bash
$ paste -d '|' <( cut -d '|' -f 1,2 file ) <( cut -d '|' -f 2 file )
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
답변3
그리고 awk
:
awk -F'|' -v OFS='|' '{if($3=="")$3=$2}1'
sed
두 번째 열이 항상 숫자인 경우 간단한 예 입니다.
sed -E "s/([0-9]*)\|$/\1|\1/"
답변4
, 를 사용하여 비어 있는지 여부를 awk
확인하세요 $3
.
awk -F'|' -v OFS='|' '$3 == "" {$3=$2} 1' file
1|100437251|100437251
2|51414204|51414204
3|111651604|111651604
4|8321737|8321737
5|27263401|27263401
- 또는
awk -F'|' -v OFS='|' 'length($3) == 0 {$3=$2} 1' file