[shell] 잘라내기를 사용하여 열 재정렬
다음 형식의 파일이 있습니다
열 1 열 2 str1 1 str2 2 str3 3
열을 다시 정렬하고 싶습니다. 나는 아래 명령을 시도했다
cut -f2,1 file.txt
이 명령은 열 순서를 바꾸지 않습니다. 왜 작동하지 않는지 아십니까?
감사합니다.
답변
에 대한 cut(1)
매뉴얼 페이지
-b, -c 또는 -f 중 하나만 사용하십시오. 각 LIST는 하나의 범위 또는 쉼표로 구분 된 많은 범위로 구성됩니다. 선택된 입력은 읽은 순서와 동일한 순서로 작성되며 정확히 한 번만 기록됩니다.
먼저 필드 1에 도달하여 인쇄되고 필드 2가옵니다.
awk
대신 사용하십시오 :
awk '{ print $2 " " $1}' file.txt
답변
또한 결합 할 수 cut
및 paste
:
paste <(cut -f2 file.txt) <(cut -f1 file.txt)
주석을 통해 : bashisms을 피하고 다음을 수행하여 컷 인스턴스를 제거 할 수 있습니다.
paste file.txt file.txt | cut -f2,3
답변
껍질 만 사용해서
while read -r col1 col2
do
echo $col2 $col1
done <"file"
답변
이를 위해 Perl을 사용할 수 있습니다.
perl -ane 'print "$F[1] $F[0]\n"' < file.txt
- -e 옵션은 명령을 실행 한 후
- -n은 한 줄씩 읽음을 의미합니다 (이 경우 STDOUT 파일을 열고 행을 반복합니다).
- -a는 이러한 행을 @F ( “F”-Field와 같은)라는 벡터로 분할하는 것을 의미합니다. Perl은 1부터 시작하는 필드를 색인화하는 cut과 달리 0에서 시작하는 벡터를 색인화합니다.
- 기본 공백 대신 파일을 읽을 때 패턴 을 필드 구분 기호로 사용하기 위해 -F 패턴 (-F와 pattern 사이에 공백이 없음)을 추가 할 수 있습니다.
펄 실행의 장점은 (펄을 알고 있다면) 열을 다시 정렬하는 것보다 F에서 훨씬 더 많은 계산을 수행 할 수 있다는 것입니다.
답변
사용 join
:
join -t $'\t' -o 1.2,1.1 file.txt file.txt
노트:
-
-t $'\t'
에서 GNUjoin
더 직관적이-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
입니다. -
쉘 스크립트 내부에서 구현할 때는 붙여 넣기 및 잘라 내기 서브 쉘을 사용하는 것이 까다로워집니다. 셸 스크립트로 가져올 때 명령 줄에서 작동하는 코드를 구문 분석하지 못합니다. 적어도 이것은 나의 경험이었습니다 (이 접근법으로 나를 이끌어 냈습니다).