파일에서 가장 긴 줄을 인쇄하는 가장 간단한 방법을 찾고 있습니다. 나는 인터넷 검색을했는데 놀랍게도 대답을 찾지 못하는 것 같습니다. 파일에서 가장 긴 줄의 길이를 자주 인쇄하지만 실제로 가장 긴 줄을 인쇄하는 방법을 모르겠습니다. 누구든지 파일에서 가장 긴 줄을 인쇄하는 솔루션을 제공 할 수 있습니까? 미리 감사드립니다.
답변
cat ./text | awk ' { if ( length > x ) { x = length; y = $0 } }END{ print y }'
UPD : 의견에 모든 조언을 요약
awk 'length > max_length { max_length = length; longest_line = $0 } END { print longest_line }' ./text
답변
cat filename | awk '{ print length }' | sort -n | tail -1
답변
sed -rn "/.{$(<file expand -t1 |wc -L)}/{p;q}" file
먼저 명령 대체 내부의 파일을 읽고 가장 긴 줄의 길이를 출력합니다 (이전 expand
의 의미를 극복하기 위해 탭을 공백으로 변환 함 wc -L
-줄의 각 탭 은 1 에서 줄 길이 대신 8 을 추가합니다 ). 그런 다음이 길이는 sed
“이 문자 수만큼 줄을 찾아서 인쇄 한 다음 종료”를 의미 하는 표현식에 사용됩니다 . 따라서 이것은 가장 긴 줄이 파일의 상단에 가까울수록 최적 일 수 있습니다.
다른 하나는 sed보다 먼저 생각했습니다 (bash).
#!/bin/bash
while read -r line; do
(( ${#line} > max )) && max=${#line} && longest="$line"
done
echo "$longest"
답변
Perl 솔루션은 다음과 같습니다.
perl -e 'while(<>){
$l=length;
$l>$m && do {$c=$_; $m=$l}
} print $c' file.txt
또는 가장 긴 줄을 모두 인쇄 하려면
perl -e 'while(<>){
$l=length;
push @{$k{$l}},$_;
$m=$l if $l>$m;
} print @{$k{$m}}' file.txt
더 나은 작업이 없었기 때문에 625M 텍스트 파일에서 일부 벤치 마크를 실행했습니다. 놀랍게도 내 Perl 솔루션은 다른 솔루션보다 지속적으로 빠릅니다. 물론 허용되는 awk
솔루션 과의 차이 는 작지만 존재합니다. 분명히 여러 줄을 인쇄하는 솔루션은 느리므로 유형별로 정렬하여 가장 빠르거나 느립니다.
가장 긴 줄 중 하나만 인쇄하십시오.
$ time perl -e 'while(<>){
$l=length;
$l>$m && do {$c=$_; $m=$l}
} print $c' file.txt
real 0m3.837s
user 0m3.724s
sys 0m0.096s
$ time awk 'length > max_length { max_length = length; longest_line = $0 }
END { print longest_line }' file.txt
real 0m5.835s
user 0m5.604s
sys 0m0.204s
$ time sed -rn "/.{$(<file.txt expand -t1 |wc -L)}/{p;q}" file.txt
real 2m37.348s
user 2m39.990s
sys 0m1.868s
가장 긴 줄을 모두 인쇄하십시오.
$ time perl -e 'while(<>){
$l=length;
push @{$k{$l}},$_;
$m=$l if $l>$m;
} print @{$k{$m}}' file.txt
real 0m9.263s
user 0m8.417s
sys 0m0.760s
$ time awk 'length >x { delete y; x=length }
length==x { y[NR]=$0 } END{ for (z in y) print y[z] }' file.txt
real 0m10.220s
user 0m9.925s
sys 0m0.252s
## This is Chris Down's bash solution
$ time ./a.sh < file.txt
Max line length: 254
Lines matched with that length: 2
real 8m36.975s
user 8m17.495s
sys 0m17.153s
답변
가장 긴 줄을 잡으십시오
grep -Em1 "^.{$(wc -L <file.txt)}\$" file.txt
이 명령은 쉘 구문과 regexp 구문을 혼합하기 때문에 연습 없이는 읽기가 매우 어렵습니다.
설명을 위해 먼저 단순화 된 의사 코드를 사용합니다. 로 시작하는 행 ##
은 쉘에서 실행되지 않습니다.
이 단순화 된 코드는 파일 이름 F를 사용하고 가독성을 위해 인용 부호와 정규 표현식의 일부를 생략합니다.
작동 원리
이 명령에는 grep
-와 wc
호출의 두 부분이 있습니다 .
## grep "^.{$( wc -L F )}$" F
이 wc
프로세스 확장에 사용되는, $( ... )
그래서 그것은 전에 실행됩니다 grep
. 가장 긴 줄의 길이를 계산합니다. 쉘 확장 구문은 혼란스러운 방식으로 정규식 패턴 구문과 혼합되므로 프로세스 확장을 분해합니다.
## wc -L F
42
## grep "^.{42}$" F
여기서 프로세스 확장은 반환 된 값으로 바뀌어 grep
사용되는 명령 줄을 만듭니다 . 이제 정규식을보다 쉽게 읽을 수 있습니다 . 줄의 시작 ( ^
)에서 끝 ( $
) 까지 정확히 일치합니다 . 그 사이의 표현은 개행을 제외한 모든 문자와 일치하며 42 번 반복됩니다. 즉, 정확히 42 자로 구성된 행입니다.
이제 실제 쉘 명령으로 돌아갑니다. grep
옵션 -E
( --extended-regexp
)을 사용하면 {}
가독성을 피할 수 없습니다 . 옵션 -m 1
( --max-count=1
)은 첫 번째 줄을 찾은 후에 중지합니다. <
의 wc
명령을 방지하기 위해, 표준 입력에 파일을 기록 wc
길이와 함께 파일 이름을 인쇄에서.
가장 긴 줄은?
두 번 나타나는 파일 이름으로 예제를 더 읽기 쉽게하기 위해 파일 이름에 변수 f
를 사용합니다 . $f
예제에서 각각 은 파일 이름으로 대체 될 수 있습니다.
f="file.txt"
첫 번째 가장 긴 줄 – 가장 긴 줄 만큼 긴 첫 번째 줄을 표시하십시오 .
grep -E -m1 "^.{$(wc -L <"$f")}\$" "$f"
보기 모두 긴 줄 – 긴 긴 라인 등으로 모든 라인을 :
grep -E "^.{$(wc -L <"$f")}\$" "$f"
쇼 마지막으로 긴 줄 – 긴 줄만큼 긴 마지막 줄을 :
tac "$f" | grep -E -m1 "^.{$(wc -L <"$f")}\$"
하나의 가장 긴 줄 -다른 모든 줄보다 가장 긴 줄을 표시 하거나 실패하십시오.
[ $(grep -E "^.{$(wc -L <"$f")}\$" "$f" | wc -l) = 1 ] && grep -E "^.{$(wc -L <"$f")}\$" "$f"
(마지막 명령은 완전한 grep 명령을 반복하므로 다른 명령보다 훨씬 비효율적입니다. 출력 wc
과 행이 쓴 행 grep
이 변수에 저장 되도록 분명히 분해해야 합니다.
가장 긴 행은 실제로 모든 행일 수 있습니다. 변수로 저장하려면 처음 두 줄만 유지하면됩니다.)
답변
다음 예제는 dmitry.malikov의 답변에 대한 주석이 되었을 것입니다. 그러나 보이지 않는 주석 공간 의 쓸모없는 사용으로 인해 여기서 볼 수있는 곳을 제시했습니다. ..
이것은 드미트리의
단일 패스 awk 방법 의 간단한 변형입니다 .
모든 “동일한 가장 긴”줄을 인쇄합니다. (참고. delete array
gawk 확장명입니다).
awk 'length >x { delete y; x=length }
length==x { y[NR]=$0 } END{ for (z in y) print y[z] }' file
답변
순수한 배쉬에서 :
#!/bin/bash
_max_length=0
while IFS= read -r _line; do
_length="${#_line}"
if (( _length > _max_length )); then
_max_length=${_length}
_max_line=( "${_line}" )
elif (( _length == _max_length )); then
_max_line+=( "${_line}" )
fi
done
printf 'Max line length: %d\n' "${_max_length}"
printf 'Lines matched with that length: %d\n' "${#_max_line[@]}"
(( ${#_max_line[@]} )) && printf '%s\n' '----------------' "${_max_line[@]}"