공백을 포함하여 줄 길이별로 텍스트 파일 정렬 Binary ave ..,

다음과 같은 CSV 파일이 있습니다

AS2345, ASDF1232, Mr. Plain Example, 110 Binary ave., Atlantis, RI, 12345, (999) 123-5555,1.56
AS2345, ASDF1232, Mrs. Plain Example, 1121110 Ternary st. 110 Binary ave .., Atlantis, RI, 12345, (999) 123-5555,1.56
AS2345, ASDF1232, Mr. Plain Example, 110 Binary ave., Liberty City, RI, 12345, (999) 123-5555,1.56
AS2345, ASDF1232, Mr. Plain Example, RI, 일부 도시, 110 Ternary ave., 12345, (999) 123-5555,1.56

공백을 포함하여 줄 길이별로 정렬해야합니다. 다음 명령에는 공백이 포함되어 있지 않습니다. 수정할 수 있도록 수정하는 방법이 있습니까?

cat $@ | awk '{ print length, $0 }' | sort -n | awk '{$1=""; print $0}'



답변

대답

cat testfile | awk '{ print length, $0 }' | sort -n -s | cut -d" " -f2-

또는 동일한 길이의 선을 원래 (의도적이지 않은) 하위 분류로 수행하려면 다음을 수행하십시오.

cat testfile | awk '{ print length, $0 }' | sort -n | cut -d" " -f2-

두 경우 모두, 최종 컷을 위해 awk에서 멀어지면서 언급 된 문제를 해결했습니다.

길이가 일치하는 라인-넥타이의 경우 수행 할 작업 :

이 질문은 길이가 일치하는 줄에 대해 추가 정렬이 필요한지 여부를 지정하지 않았습니다. 나는 이것이 원치 않는 것으로 가정하고 그러한 줄이 서로 정렬되는 것을 방지하고 입력에서 발생하는 상대적 순서로 유지하기 위해 -s( --stable) 사용을 제안했습니다 .

(이 관계를 더 잘 제어하려는 사람들은 sort의 --key옵션을 볼 수 있습니다 .)

질문의 시도 된 솔루션이 실패하는 이유 (awk 라인 재 구축) :

다음의 차이점을 주목하는 것이 흥미 롭습니다.

echo "hello   awk   world" | awk '{print}'
echo "hello   awk   world" | awk '{$1="hello"; print}'

그들은 각각 항복

hello   awk   world
hello awk world

의 관련 섹션 (둔한의) 매뉴얼은 단지 당신이 하나 개의 필드를 변경하면 AWK는 (등, 분리 기준) $ 0 전체를 다시 진행하고 있음을 옆으로 언급하고있다. 나는 그것이 미친 행동이 아니라고 생각합니다. 그것은 이것을 가지고 있습니다 :

“마지막으로 필드의 현재 값과 OFS를 사용하여 awk가 전체 레코드를 다시 작성하는 것이 편리한 경우가 있습니다.

 $1 = $1   # force record to be reconstituted
 print $0  # or whatever else with $0

“이로 인해 awk는 레코드를 다시 작성해야합니다.”

길이가 같은 일부 라인을 포함한 테스트 입력 :

aa A line   with     MORE    spaces
bb The very longest line in the file
ccb
9   dd equal len.  Orig pos = 1
500 dd equal len.  Orig pos = 2
ccz
cca
ee A line with  some       spaces
1   dd equal len.  Orig pos = 3
ff
5   dd equal len.  Orig pos = 4
g


답변

neillbAWK 솔루션은 실제로 사용 awk하고 싶을 때 유용 하며, 그 이유가 무엇인지 설명하지만 원하는 작업을 신속하게 수행하고 수행하는 작업을 신경 쓰지 않는 경우 하나의 솔루션을 사용하는 것입니다 sort()입력 라인을 반복하는 커스텀 caparison 루틴을 가진 Perl의 기능. 하나의 라이너는 다음과 같습니다.

perl -e 'print sort { length($a) <=> length($b) } <>'

STDIN을 수신 cat하거나 ( 쉘 리다이렉션을 통해) 파이프 라인에 필요 하거나 파일 이름을 다른 인수로 perl하여 파일을 열 수 있습니다.

내가 스왑 그래서 내 경우에는 내가 먼저 긴 줄을 필요로 $a하고 $b비교에.


답변

대신이 명령을 시도하십시오.

awk '{print length, $0}' your-file | sort -n | cut -d " " -f2-


답변

벤치 마크 결과

다음은이 질문에 대한 다른 답변의 솔루션에 대한 벤치 마크 결과입니다.

테스트 방식

  • 빠른 기계에서 평균 10 회 연속 실행
  • 펄 5.24
  • awk 3.1.5 (gawk 4.1.0 배 ~ 2 % 빠름)
  • 입력 파일은 550MB, 6 백만 줄의 괴물입니다 (British National Corpus txt)

결과

  1. 칼렙 perl 솔루션 은 11.2 초 걸렸습니다
  2. 나의 perl 솔루션 은 11.6 초 걸렸다
  3. neillb의 awk 솔루션 # 1은 20 초가 걸렸습니다
  4. neillb의 awk 솔루션 # 2는 23 초가 걸렸습니다
  5. 아누 바 awk 솔루션 은 24 초가 걸렸습니다
  6. 조나단 awk 솔루션 은 25 초가 걸렸습니다
  7. Fretz의 bash솔루션 은 보다 400 배 더 오래 걸립니다 awk(100000 줄의 잘린 테스트 사례 사용). 잘 작동하고 영원히 걸립니다.

추가 perl옵션

또한 다른 Perl 솔루션을 추가했습니다.

perl -ne 'push @a, $_; END{ print sort { length $a <=> length $b } @a }' file


답변

순수한 배쉬 :

declare -a sorted

while read line; do
  if [ -z "${sorted[${#line}]}" ] ; then          # does line length already exist?
    sorted[${#line}]="$line"                      # element for new length
  else
    sorted[${#line}]="${sorted[${#line}]}\n$line" # append to lines with equal length
  fi
done < data.csv

for key in ${!sorted[*]}; do                      # iterate over existing indices
  echo -e "${sorted[$key]}"                       # echo lines with equal length
done


답변

length()함수는 공간을 포함한다. 파이프 라인을 약간만 조정하면됩니다 ( UUOC 피하기 포함 ).

awk '{ printf "%d:%s\n", length($0), $0;}' "$@" | sort -n | sed 's/^[0-9]*://'

sed명령 은 명령에 의해 추가 된 숫자와 콜론을 직접 제거합니다 awk. 또는 형식을 awk다음 에서 유지하십시오 .

awk '{ print length($0), $0;}' "$@" | sort -n | sed 's/^[0-9]* //'


답변

파일에 숫자로 시작하는 줄이 포함되어 있으면이 솔루션이 작동하지 않는다는 것을 알았습니다. 숫자로 정렬 된 모든 줄과 숫자로 정렬되기 때문입니다. 이 솔루션은 제공하는 것입니다 대신 플래그 (일반 숫자-종류) (숫자-종류) :sort-g-n

awk '{ print length, $0 }' lines.txt | sort -g | cut -d" " -f2-