제가 변환하려는 파일은 다음과 같습니다.
john doe
555-666-333
[email protected]
die
jane doe
Beverly Hills
444-333-111
[email protected]
die
결과 파일이 다음과 같기를 원합니다.
john doe,555-666-333,[email protected]
jane doe,Beverly Hills,444-333-111,[email protected]
단어가 die
파일에 있으며 위에 표시된 대로 출력에 표시되지 않도록 이 단어를 사용하여 줄을 구분하고 싶습니다.
편집하다
파일 형식을 변경했습니다. 전자 형식은 단어 수가 단어마다 다를 수 있다는 사실을 고려하지 않습니다 die
.
답변1
$ awk -v OFS=',' '/^die$/ { print substr(lines,2); lines=""; next } { lines=lines OFS $0 }' file
john doe,555-666-333,[email protected]
jane doe,Beverly Hills,444-333-111,[email protected]
쉼표가 포함된 데이터에도 동일한 내용이 적용됩니다(아래 답변의 끝 부분 참조). 데이터에 쉼표가 포함된 경우 다음을 사용할 수 있습니다.
awk -v OFS=',' '
/^die$/ { print substr(lines,2); lines=""; next }
/,/ { $0=sprintf("\"%s\"", $0 ) }
{ lines=lines OFS $0 }' file
이 코드는 (쉼표) lines
로 구분된 문자열을 작성합니다. 한 줄에 OFS
단어 자체가 있으면 해당 문자열을 출력합니다. 이 호출은 레코드의 첫 번째 필드가 문자열에 추가될 때 줄 앞에 추가된 쉼표를 제거합니다. 쉼표가 있는 줄은 아래 코드와 동일한 방식으로 처리됩니다.die
lines
substr()
GNU awk
또는 BSD를 사용하여 이 작업을 수행할 수도 있지만 mawk
BSD는 사용할 수 없습니다.awk
mawk -v RS='\ndie\n' -v FS='\n' -v ORS='\n' -v OFS=',' '{$1=$1;print}' file
쉼표가 포함된 데이터에 대해서는 따옴표 붙은 필드를 생성하지 않습니다.
출력 전에 (출력 필드 구분자) 및 (출력 레코드 구분자) 변수를 기반으로 레코드를 $1=$1
강제로 재구성합니다 awk
.OFS
ORS
질문을 업데이트하기 전에 대답하십시오:
paste -d, - - - - <file
이것은 생산할 것입니다
john doe,555-666-333,[email protected],die
jane doe,444-333-111,[email protected],die
이 줄을 제거하려면 die
(완전히 불필요함):
paste -d, - - - - <file | cut -d, -f 1-3
위 방법은 원본 데이터에 쉼표가 포함되어 있지 않은 경우에 작동합니다.
die
처음부터 행을 필터링 할 수도 있습니다 .
sed '/^die$/d' file | paste -d, - - -
이는 원본 데이터에 쉼표가 포함된 경우에도 작동합니다.
데이터에 쉼표가 포함된 경우 이를 전처리하여 줄 주위에 따옴표를 추가해야 할 수도 있습니다.
awk '/^die$/ { next } /,/ { $0=sprintf("\"%s\"", $0 ) } 1' file | paste -d, - - -
주어진 파일
john doe
555-666-333
[email protected]
die
jane doe
444-333-111
[email protected]
die
Me, myself and I
000-000-000
[email protected]
마지막 명령은 생성됩니다
john doe,555-666-333,[email protected]
jane doe,444-333-111,[email protected]
"Me, myself and I",000-000-000,[email protected]
답변2
다음과 같은 관용구를 사용하여 이를 수행할 수 있습니다 awk
.
$ awk '$1=$1' RS='.die\n' OFS="," FS='\n' file1
john doe,555-666-333,[email protected]
jane doe,Beverly Hills,444-333-111,[email protected]
위에서는 기록 구분 기호를 파일에서 개인 세부 정보를 구분하는 데 사용되는 항목 으로 awk
정의했습니다 .RS
die
$1=$1
출력 필드 구분 기호로 ","를 사용하여 awk가 입력 필드를 다시 계산하고 인쇄하도록 강제합니다.OFS
추신: 가능한 문자 제거를 \r
호출하는 데 사용하는 것처럼 파일 끝에 문제가 있다고 의심되는 경우 :tr
\r
tr -d '\r' file1 |awk .....
그런데 sed를 다음과 같이 사용할 수도 있습니다.
$ sed -z 's/\n/,/g; s/,die,/\n/g'
이는 sed를 속여 널 문자를 레코드 구분 기호로 사용함으로써 awk와 동일한 출력을 생성합니다.
입력 파일에 실제 널 문자가 없으면 sed는 전체 입력 파일을 하나의 큰 레코드 == 하나의 큰 줄로 처리합니다.
답변3
이는 "sed" 편집기를 사용하여 POSIX 방식으로 수행할 수 있습니다.
sed -e '
:a
$q;N;y/\n/,/
s/,die$//;t
ba
' input_file
방법:
- 루프를 설정하고 패턴 공간에 다음 줄을 추가합니다.
- 질소주문하다
- 개행 문자를 쉼표로 변경하고 ",die"를 제거해 보세요.
- 예/// 에스///주문하다
- 성공하면 모든 것이 준비된 것이므로 추가 처리가 필요하지 않습니다.
- 티레이블이 없는 명령
- 그렇지 않으면, 우리가 끝내고 그만둘 경우를 대비해 돌아가서 더 많은 것을 얻으십시오.
- 비 그리고 큐 주문하다.
이 목적으로 Perl을 사용할 수도 있습니다.
perl -lne '
push @A, $_ unless /^die$/;
print join ",", splice @A if /^die$/ || eof;
' input_file
"주사위" 행이 보일 때까지 배열에 행을 축적합니다. 이 시점에서 우리는 쉼표를 통해 배열 내용을 연결합니다(또한 배열을 지웁니다).
파일을 읽은 다음 Perl을 호출하여 결과를 얻을 수도 있습니다.
perl -lF'/^die\n/m' -0777nae 'print join ",", split /\n/ for @F' input_file
- -에프'/^die\n/m'은 파일을 정규식 BOL 다이의 줄 바꿈이 뒤따르는 문자열로 분할합니다.
- -0777은 빨기 소리를 냅니다.-N라인 자동 인쇄 및-ㅏ을 기반으로 할 것이다-에프값.