답변:
-F
옵션은 인수를 필요 : -F,
예를 들면.
awk
스크립트 의 끝은 나머지 매개 변수와 함께 (공백 문자) 로 분리해야합니다 .
필드 구분 기호가 ,
있고 유지하려는 경우 열 수가 일정하고 11보다 작거나 같은 경우 다음을 시도하십시오.
awk -F, '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' OFS=, "$file"
command file > newfile && mv newfile file
입니다. 즉, awk
이것을 지원하는 최신 버전의 GNU : gawk -i inplace '{blah blah}' file
.
mv newfile file
사용할 수 있습니다 cat newfile > file ; rm -f newfile
.-의 inode 및 권한이 유지 file
됩니다.
mktemp
임시 파일 이름을 스크립트로 하드 코딩 하는 대신 사용하는 것이 좋습니다 . 예tf=$(mktemp) ; command file > "$tf" ; cat "$tf" > file ; rm -f "$tf"
더 짧은 해결책은
awk -F',+' -v OFS=, '{$(NF+1)=$7; $7=""; $0=$0; $1=$1}1' file
,+
모든 awk
버전 에서 작동 하는지 확실하지 않지만 최소한 GNU awk에서도 작동하며 -c
ompatibility 모드 에서도 작동합니다.
설명:
$(NF+1)=$7
: 먼저 우리는 줄의 끝에 7 번째 필드를 추가합니다 ( $12=$7
이 경우 가능)$7=""
: 다음 단계에서 7 번째 필드가 지워집니다 (그러나 주변 구분 기호는 그대로 유지됨)$0=$0
(이 통해 이루어진다 필드 분리 여러개 쉼표 처리) -F',+'
여기서, +
하나 개 또는 그 이상을 의미한다), 또한 통해 현재 레코드를 재 배열 $1=$1
이전에 설정된 출력 필드를 사용하여 광고를 다시 강제 구분 기호 (옵션으로 설정 -v OFS=,
)1
입력 예 :
1,2,3,4,5,6,7,8,9,10,11
산출
1,2,3,4,5,6,8,9,10,11,7
,+
일 경우 작동합니다.
all,ball,call,,,fall
→ all,ball,call,fall
). (2) $(NF+1)=$7
는 영리한 접근법입니다. IMHO $0 = $0 OFS $7
는 조금 더 명확하고 두 글자 만 길며 같은 일을하는 것처럼 보입니다. $0 = $0 OFS $7
코드와 동일하지 않은 상황을 생각할 수 있습니까 ?
$0=$0 OFS $7
아마 동일 $(NF+1)=$7
하지만 나머지 코드는 변경되지 않고 일반적으로 변경되지 않습니다.
당신은 아마 의미 :
awk -F, -v OFS='' '{print $1,$2,$3,$4,$5,$6,$8,$9,$10,$11,$7}' "$file"
awk
에서 작은 따옴표 를 보지 못한다는 것을 알고 OFS=''
있습니까? 당신은뿐만 아니라 입력 할 수 있습니다 OFS=
; 정확히 동일합니다.
당신은 특별히 awk 를 사용하고 싶다고 말하지 않았고 에서 제공 한 것처럼 내부 편집을 사용하고 싶다고 말 sed -i
했으므로 여기에 sed -i
변형이 있습니다. 일반적 awk
으로 열을 사용하는 것이 더 좋지만 sed
자연스럽게 임의의 수의 열을 처리하기 때문에 선호하는 경우 입니다.
MOVECOL=7
N=$((MOVECOL-1))
sed -r -e "s/^(([^,]*,){$N})([^,]*),(.*)/\1\4,\3/" -i test.csv
설명:
-r
확장 정규 표현식을 선택하여 많은 백 슬래시를 피합니다.물론 이것은 따옴표로 쉼표를 숨기는 파일 (또는 더 나쁘게 탈출)에서는 작동하지 않지만 awk는 심각한 곡예가 없으면 처리하지 않습니다. 당신은 그 문제가있는 경우가 더 나을 것 perl
모듈 Text:CSV
또는 python
모듈 csv
.
몇 가지 awk
변형 (파일이 변수 안에 있다고 가정 $file
)
여기에서 모든 열량을 순환하고 필드 구분 기호 (OFS)로 인쇄하고 줄 끝에서 레코드 종결 자 (ORS)를 인쇄 할 수 있습니다.
awk -F',' -v OFS=, \
'{for(i=1;i<=NF;i++) if (i!=7) printf "%s",$i OFS; \
printf "%s",$7;printf ORS}' "$file"
여기에 정규식과 gensub()
함수 를 사용하여
gawk -F',+' -v OFS=, '{$0=gensub(/\s*\S+/,"",7) OFS $7}1' "$file"
7 번째 필드를 죽이고 줄의 끝에 그것을 인쇄하십시오.
$0
전체 기록이다 $n
n 번째 레코드입니다 NF
현재 줄의 필드 수 OFS
출력 된 구분 기호ORS
출력 레코드 종결 자1
awk라고 말하고 true
기본값 ( $0
)을 인쇄 하는 트릭 입니다.업데이트 ...
거의 잊어 버렸습니다 .7 번째 행을 따라 모든 열을 이동할 수 있습니다 .
awk -F',' -v OFS=, '{tmp=$7; for(i=7;i<=NF;i++) $i=$(i+1); $NF=tmp}1 ' "$file"
OFS $7
보다 더 강력한 것입니다 "," $7
. (2) ", " $7
OP가 쉼표 뒤에 공백을 원하지 않는다는 질문이 나타내는 한, 나는 이것이 잘못 되었다고 생각 합니다. (그리고 입력 데이터에 쉼표 뒤에 공백 $7
이 있으면 이미 공백으로 시작하고 추가 공백을 추가 할 것입니다.)
OFS $7
뿐만 아니라 더 강력하지만 더 일반적인 ( "서둘러 폐기물한다" )
^
오류가 발생 된 명령의 특정 부분을 나타냅니다.