구분자를 사용하여 목록을 한 줄로 바꾸기 109.21.244.0 파이프를 사이에두고이 형식으로 바꾸십시오 (IP 구성). 134.27.128.0

이 형식으로 IP 주소 목록을 가져와야합니다.

 134.27.128.0
 111.245.48.0
 109.21.244.0

파이프를 사이에두고이 형식으로 바꾸십시오 (IP 구성).

134.27.128.0 | 111.245.48.0 | 109.21.244.0 | 103.22.200.0/22

나는 그것이 찾기 및 바꾸기 명령이라고 생각 sed하지만 작동시킬 수는 없습니다.



답변

Famous Sed One-Liners Explained, Part I : : 39를 기반으로 sed를 사용 합니다. 백 슬래시 “\”로 끝나는 경우 다음 행을 추가합니다 (여기서는 백 슬래시 관련 부분을 무시하고 줄 \n바꿈을 필요한 |구분 기호) :

sed -e :a -e '$!N; s/\n/ | /; ta' mydoc > mydoc2

생산해야한다 mydoc2

134.27.128.0 |  111.245.48.0 |  109.21.244.0


답변

나는 이들 (+ 일부 대안) 중 일부가 다소 큰 파일 ( 163MiBIP줄에 하나씩 ~ 1,300 만 줄)로 속도면에서 어떻게 작동하는지 궁금했습니다 .

wc -l < iplist
13144256

결과 ( sync; echo 3 > /proc/sys/vm/drop_caches각 명령 후; 몇 시간 후에 역순으로 테스트를 반복했지만 차이점은 무시할 수있었습니다 gnu sed.

스틸 드라이버 :
매우 느립니다. 2 분 동안 기다린 후에 중단되었으므로 결과가 없습니다.

cuonglm :

awk 'FNR!=1{print l}{l=$0};END{ORS="";print l}' ORS=' | ' iplist

real    0m3.672s

perl -pe 's/\n/ | / unless eof' iplist

real    0m12.444s

mikeserv :

paste -d\  /dev/null iplist /dev/null | paste -sd\| -

real    0m0.983s

jthill :

sed 'H;1h;$!d;x;s/\n/ | /g' iplist

real    0m4.903s

아비 나쉬 라지 :

time python2.7 -c'
import sys
with open(sys.argv[1]) as f:
    print " | ".join(line.strip() for line in f)' iplist

real    0m3.434s

val0x00ff :

while read -r ip; do printf '%s | ' "$ip"; done < iplist

real    3m4.321s

의미 184.321s합니다. 당연히, 이것은 mikeserv 솔루션 보다 200 배 느립니다 .


awk를 사용 하는 다른 방법은 다음과 같습니다 .

awk '$1=$1' RS= OFS=' | ' iplist

real    0m4.543s

awk '{printf "%s%s",sep,$0,sep=" | "} END {print ""}' iplist

real    0m5.511s

펄 :

perl -ple '$\=eof()?"\n":" | "' iplist

real    0m9.646s

xargs :

xargs <iplist printf ' | %s' | cut -c4-

real    0m6.326s

head + paste + tr + cat 조합 :

{ head -n -1 | paste -d' |' - /dev/null /dev/null | tr \\n \ ; cat ; } <iplist

real    0m0.991s

보유 GNU coreutils하고 있고 IP 목록이 실제로 크지 않은 경우 (최대 50000 개의 IP) 다음과 pr같이 할 수도 있습니다 .

pr -$(wc -l infile) -tJS' | ' -W1000000 infile >outfile

어디

-$(wc -l infile)         # no. of columns (= with no. of lines in your file)
-t                       # omit page headers and trailers
-J                       # merge lines
-S' | '                  # separate columns by STRING
-W1000000                # set page width

예를 들어 6 줄 파일의 경우 :

134.28.128.0
111.245.28.0
109.245.24.0
128.27.88.0
122.245.48.0
103.44.204.0

명령 :

pr -$(wc -l <infile) -tJS' | ' -W1000 infile

출력 :

134.28.128.0 | 111.245.28.0 | 109.245.24.0 | 128.27.88.0 | 122.245.48.0 | 103.44.204.0


답변

awk 를 사용할 수 있습니다 :

awk 'FNR!=1{print l}{l=$0};END{ORS="";print l}' ORS=' | ' file > new_file

ORS=' | '출력 레코드 구분 기호' | '개행 문자 대신 설정하십시오 .

또는 다음 위치에서 편집하십시오 perl.

perl -pe 's/\n/ | / unless eof' file


답변

그래서 나는 모든 것이 잘못되었다. 그리고이 질문은 나에게 많은 것을 가르쳐 주었다 paste. cuonglm이 올바르게 지적했듯이, in inial paste파일이 없으면 infile 목록 -s의 마지막 \newline이 출력에 추가 될 때 항상 출력됩니다. 나는 paste -s행동이 기본 모드 라는 믿음으로 착각했습니다. 이것은 분명히 busybox paste기뻐 하는 오해입니다 . 다음 명령은 광고 된대로 작동합니다 busybox.

paste -d'|  ' - - infile </dev/null >outfile

그러나 사양에 따라 작동하지 않습니다. 올바르게 구현 paste되면 \n각 시퀀스에 대해 후행 줄 바꿈이 추가 됩니다. 여전히, 그것은 결국 큰 문제가 아닙니다.

paste -d\  - infile - </dev/null | paste -sd\| - >outfile


답변

tr과 sed를 가진 1 개의 강선 :

cat file | tr '\n' '|' | sed 's/||$/\n/'
134.27.128.0|111.245.48.0|109.21.244.0


답변

활용 vim:

vim -n -u NONE -c '1,$-1s/\n/ | /g|wq!' data

설명:

-n 스왑 파일 비활성화

-u NONE 모든 초기화를 건너 뛰는 데 사용됩니다.

-c {command} 파일을 읽은 후 명령을 실행하십시오.

1,$-1s/\n/ | /g되는 s/\n/ | /g범위의 (공간 배관 공간 개행 교환) 1,$-1s(마지막 라인에 1 라인 – 1)

wq! 강제 쓰기 및 종료


노트 :

파일의 실제 크기에 따라 나쁜 생각 일 수 있습니다.


답변

파이썬을 통해.

$ python -c '
import sys
with open(sys.argv[1]) as f:
    print " | ".join(line.strip() for line in f)' file

전에 공백 print이 매우 중요했습니다.