스크립트에 의해 자동으로 생성된 csv 파일이 있지만 수신된 특정 레코드(품목)에 대해 열 2를 검색해야 하고 값에 "*.app"이 포함되어 있으면 열 2에 "INVALID"를 인쇄해야 합니다. 그리고 셀을 오른쪽으로 이동합니다.
데이터 파일 예:
DOM,PROJ,APP,USER,DATE,TIME,STATUS
www,test,biz.app,bob,6-1-18,09:33,OK //Example of good line
www,biz.app,tony,7-11-17,06:22,ok //Example of bad line
...
Wanted output:
DOM,PROJ,APP,USER,DATE,TIME,STATUS
www,test,biz.app,bob,6-1-18,09:33,OK
www,INVALID,biz.app,tony,7-11-17,06:22,ok //Example of fixed line
...
awk, sed 및 if 문을 시도했지만 성공하지 못했지만 필요한 결과를 얻지 못했습니다.
e.g.
if [ awk -F',' '{ print $2 } < FILE' ] == "*.app" ; then ; echo "INVALID"; fi
이것은 확실히 나쁜 일입니다...bash를 처음 접한 여러분 감사합니다!
답변1
awk -F, -vOFS=, '$2 ~ /\.app$/ { for (i = NF + 1; i > 2; --i) $i = $(i-1); $2 = "INVALID" } 1' file >newfile
이 newfile
명령은 입력 및 출력 필드 구분 기호를 쉼표로 설정한 다음 값 끝에 있는 문자열과 일치하는 정규식을 기반으로 두 번째 열의 값을 테스트합니다 file
. 테스트가 성공하면 레코드의 필드가 오른쪽으로 한 위치 이동되어 문자열을 새로운 두 번째 필드로 위한 공간을 확보합니다.awk
.app
INVALID
꼬리는 1
다음으로 대체될 수 있습니다 { print }
(이렇게 하면 모든 줄이 출력됩니다).
주어진 샘플 데이터의 경우 출력 파일에는 다음이 포함됩니다.
DOM,PROJ,APP,USER,DATE,TIME,STATUS
www,test,biz.app,bob,6-1-18,09:33,OK
www,INVALID,biz.app,tony,7-11-17,06:22,ok
답변2
Awk
방법:
awk 'BEGIN{ FS = OFS = "," }NR > 1 && $2 ~ /.*\.app/{ $2 = "INVALID" OFS $2 }1' file
NR > 1 && $2 ~ /.*\.app/
- 레코드 번호가1
(첫 번째를 제외한 모든 레코드)보다 크고 두 번째 필드가$2
패턴과 일치하는 경우/.*\.app/
산출:
DOM,PROJ,APP,USER,DATE,TIME,STATUS
www,test,biz.app,bob,6-1-18,09:33,OK
www,INVALID,biz.app,tony,7-11-17,06:22,ok
답변3
이 GNU sed
도구를 사용하면 다음과 같이 이 문제를 해결할 수 있습니다.
sed -e '
1!s/,/\n&/2
/\.app\n/s/,/,INVALID,/
s/\n//
' file.csv
읽다:
° Only for lines that are not the first, meaning, skip the header from being considered for processing, whilst for the others, place a marker at the second occurrence of the comma.
° Any line that has the 2nd field terminating in a .app append the string INVALID after the first field.
° Now take away the marker.
° N. B. Lines whose 2nd field doesn't comprise *.app are passed on unmodified.