답변:
에 대한 cut(1)
매뉴얼 페이지
-b, -c 또는 -f 중 하나만 사용하십시오. 각 LIST는 하나의 범위 또는 쉼표로 구분 된 많은 범위로 구성됩니다. 선택된 입력은 읽은 순서와 동일한 순서로 작성되며 정확히 한 번만 기록됩니다.
먼저 필드 1에 도달하여 인쇄되고 필드 2가옵니다.
awk
대신 사용하십시오 :
awk '{ print $2 " " $1}' file.txt
FS
. 옵션이며 OFS
변수입니다. 예awk -v OFS=";" -F"\t" '{print $2,$1}'
| sed 's/\r//' |
배관 전에awk
awk '{print $4 "\t" $2 "\t" $6 "\t" $7}' file
또한 결합 할 수 cut
및 paste
:
paste <(cut -f2 file.txt) <(cut -f1 file.txt)
주석을 통해 : bashisms을 피하고 다음을 수행하여 컷 인스턴스를 제거 할 수 있습니다.
paste file.txt file.txt | cut -f2,3
cut
고유 한 열 구분 기호가 있으면 가변 길이 열에 적합합니다.
bash
isms 를 피하고 하나의 인스턴스를 제거 할 수 있습니다 cut
. paste file.txt file.txt | cut -f2,3
이를 위해 Perl을 사용할 수 있습니다.
perl -ane 'print "$F[1] $F[0]\n"' < file.txt
펄 실행의 장점은 (펄을 알고 있다면) 열을 다시 정렬하는 것보다 F에서 훨씬 더 많은 계산을 수행 할 수 있다는 것입니다.
perl -ae print
작동cat
사용 join
:
join -t $'\t' -o 1.2,1.1 file.txt file.txt
노트:
-t $'\t'
에서 GNU join
더 직관적이 -t '\t'
없이 (가) $
실패, ( 로 coreutils는 v8.28 이전?); 아마도 해결 방법 $
이 필요한 버그 일 것입니다 . 유닉스 조인 구분자 char 참조 .
join
하나의 파일 만 작업 중이지만 두 개의 파일 이름이 필요합니다. 같은 이름을 두 번 사용하여 속임수join
원하는 작업을 수행 할 수 있습니다.
리소스가 적은 시스템 join
의 경우 다른 답변에 사용 된 일부 도구보다 설치 공간이 작습니다.
wc -c $(realpath `which cut join sed awk perl`) | head -n -1
43224 /usr/bin/cut
47320 /usr/bin/join
109840 /bin/sed
658072 /usr/bin/gawk
2093624 /usr/bin/perl
방금 비슷한 일을하고 있었지만 전문가는 아니지만 내가 사용한 명령을 공유한다고 생각했습니다. 다중 열 csv가 있었는데 4 열만 필요했고 다시 정렬해야했습니다.
내 파일은 파이프 '|' 구분되지만 교환 할 수 있습니다.
LC_ALL=C cut -d$'|' -f1,2,3,8,10 ./file/location.txt | sed -E "s/(.*)\|(.*)\|(.*)\|(.*)\|(.*)/\3\|\5\|\1\|\2\|\4/" > ./newcsv.csv
틀림없이 그것은 정말로 거칠고 준비가되어 있지만, 그에 맞게 조정할 수 있습니다!
sed 사용
기본 정규식의 중첩 된 하위 표현식과 함께 sed를 사용하여 열 컨텐츠를 캡처하고 순서를 변경하십시오. 이 방법은이 경우와 같이 열 순서를 변경하기 위해 컷 수가 제한되어있을 때 가장 적합합니다.
기본 아이디어는 \(
및로 검색 패턴의 흥미로운 부분을 둘러싸 \)
는 것입니다 \#
.#
검색 패턴의 표현식의 순차적 위치를 나타낸다.
예를 들면 다음과 같습니다.
$ echo "foo bar" | sed "s/\(foo\) \(bar\)/\2 \1/"
수율 :
bar foo
하위 표현식 외부의 텍스트는 스캔되지만 대체 문자열에서 재생할 수 있도록 유지되지 않습니다.
이 질문은 고정 너비 열에 대해서는 다루지 않았지만 여기서는 해결 된 솔루션의 가치있는 척도이므로 여기서 논의 할 것입니다. 간단하게하기 위해 파일을 공간 구분 된 것으로 가정하지만 솔루션을 다른 구분 기호로 확장 할 수 있습니다.
접는 공간
가장 간단한 사용법을 설명하기 위해 여러 공백을 단일 공백으로 축소 할 수 있고 두 번째 열 값이 공백으로 채워지지 않은 EOL로 종료된다고 가정합니다.
파일:
bash-3.2$ cat f
Column1 Column2
str1 1
str2 2
str3 3
bash-3.2$ od -a f
0000000 C o l u m n 1 sp sp sp sp C o l u m
0000020 n 2 nl s t r 1 sp sp sp sp sp sp sp 1 nl
0000040 s t r 2 sp sp sp sp sp sp sp 2 nl s t r
0000060 3 sp sp sp sp sp sp sp 3 nl
0000072
변환:
bash-3.2$ sed "s/\([^ ]*\)[ ]*\([^ ]*\)[ ]*/\2 \1/" f
Column2 Column1
1 str1
2 str2
3 str3
bash-3.2$ sed "s/\([^ ]*\)[ ]*\([^ ]*\)[ ]*/\2 \1/" f | od -a
0000000 C o l u m n 2 sp C o l u m n 1 nl
0000020 1 sp s t r 1 nl 2 sp s t r 2 nl 3 sp
0000040 s t r 3 nl
0000045
열 너비 유지
너비가 다른 열을 허용하면서 너비가 일정한 열이있는 파일로 메서드를 확장 해 보겠습니다.
파일:
bash-3.2$ cat f2
Column1 Column2
str1 1
str2 2
str3 3
bash-3.2$ od -a f2
0000000 C o l u m n 1 sp sp sp sp C o l u m
0000020 n 2 nl s t r 1 sp sp sp sp sp sp sp 1 sp
0000040 sp sp sp sp sp nl s t r 2 sp sp sp sp sp sp
0000060 sp 2 sp sp sp sp sp sp nl s t r 3 sp sp sp
0000100 sp sp sp sp 3 sp sp sp sp sp sp nl
0000114
변환:
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f2
Column2 Column1
1 str1
2 str2
3 str3
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f2 | od -a
0000000 C o l u m n 2 sp C o l u m n 1 sp
0000020 sp sp nl 1 sp sp sp sp sp sp sp s t r 1 sp
0000040 sp sp sp sp sp nl 2 sp sp sp sp sp sp sp s t
0000060 r 2 sp sp sp sp sp sp nl 3 sp sp sp sp sp sp
0000100 sp s t r 3 sp sp sp sp sp sp nl
0000114
마지막으로 질문 예제에 길이가 다른 문자열이 없지만이 sed 표현식은이 경우를 지원합니다.
파일:
bash-3.2$ cat f3
Column1 Column2
str1 1
string2 2
str3 3
변환:
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f3
Column2 Column1
1 str1
2 string2
3 str3
bash-3.2$ sed "s/\([^ ]*\)\([ ]*\) \([^ ]*\)\([ ]*\)/\3\4 \1\2/" f3 | od -a
0000000 C o l u m n 2 sp C o l u m n 1 sp
0000020 sp sp nl 1 sp sp sp sp sp sp sp s t r 1 sp
0000040 sp sp sp sp sp nl 2 sp sp sp sp sp sp sp s t
0000060 r i n g 2 sp sp sp nl 3 sp sp sp sp sp sp
0000100 sp s t r 3 sp sp sp sp sp sp nl
0000114
쉘에서 다른 열 순서 변경 방법과 비교
놀랍게도 파일 조작 도구의 경우 awk는 필드에서 레코드 끝까지 자르기에 적합하지 않습니다. sed에서는 정규 표현식을 사용하여이를 수행 할 수 있습니다. 예를 들어 , 표현식이 열과 일치하는 \(xxx.*$\)
위치 xxx
입니다.
쉘 스크립트 내부에서 구현할 때는 붙여 넣기 및 잘라 내기 서브 쉘을 사용하는 것이 까다로워집니다. 셸 스크립트로 가져올 때 명령 줄에서 작동하는 코드를 구문 분석하지 못합니다. 적어도 이것은 나의 경험이었습니다 (이 접근법으로 나를 이끌어 냈습니다).
@Met의 답변을 확장하고 Perl도 사용
하십시오. 입력 및 출력이 TAB로 구분 된 경우 :
perl -F'\t' -lane 'print join "\t", @F[1, 0]' in_file
입력과 출력이 공백으로 구분 된 경우 :
perl -lane 'print join " ", @F[1, 0]' in_file
여기서는
-e
별도의 스크립트 파일이 아닌 코드 인라인을 찾고 Perl에게
-n
한 번에 한 줄씩
-l
입력 \n
을 읽고, 줄을 읽은 후 ( * NIX에서) 입력 레코드 구분 기호를 제거하고 chomp
출력을 추가 하도록 지시 합니다. (기록 세퍼레이터 \n
각각에 NIX *)는 print
,
-a
어레이에 공백의 입력 라인을 분리 @F
,
-F'\t'
조합하여 -a
스플릿 배열에 입력 탭 선 대신 공백 @F
.
@F[1, 0]
는 배열의 두 번째 및 첫 번째 요소로 구성된 배열 @F
입니다. Perl의 배열은 인덱스가 0이고, 필드 cut
는 1 인덱스입니다. 에있는 필드 @F[0, 1]
는의 필드와 동일한 필드입니다 cut -f1,2
.
이러한 표기법은 위에 게시 된 다른 답변보다 간단한 입력 조작을 가능하게합니다 (간단한 작업에는 적합합니다). 예를 들면 다음과 같습니다.
# reverses the order of fields:
perl -F'\t' -lane 'print join "\t", reverse @F' in_file
# prints last and first fields only:
perl -F'\t' -lane 'print join "\t", @F[-1, 0]' in_file
cut
이 직관적 재정렬 명령을 지원하지 않는 것은 너무 나쁩니다 . 어쨌든, 또 다른 팁 : 당신은 사용할 수awk
의-FS
및-OFS
사용 사용자 정의 입력하고 (같은 출력 필드 분리에 옵션을-d
과--output-delimiter
에 대한cut
).