"tac"구현 : 파일에서 줄을 반대로 인쇄


30

사이에 새끼 고양이 질문 및보고 U & L에서이 질문을 몇 가지에 대해 sed어떻게 구현에 대해, 마법 tac?


목표

파일의 행을 뒤집어 인쇄하는 프로그램을 구현하십시오.


입력

이름 또는 표준 입력을 통해 제공되는 파일


산출

라인이 표준 출력으로 반전되었습니다.


채점

바이트의 소스 코드.


9
tac후행 줄 바꿈에 관해서는 조금 이상합니다. 이 변환 a\nb\n에 (뒤 바꿈) b\na\na\nb로 (후행를 바꿈) ba\n. 이것이 우리 코드가 어떻게 행동해야합니까?
Dennis


10
또한 tac의 행동을 복제해야한다면, 실행되는 3 바이트 Bash 응답 tac은 시간 문제 일뿐입니다.
Dennis

1
이 시점에서 @Dennis는 아마도 정의되지 않은 채로 두는 것이 가장 좋습니다.
Nick T

1
@Dennis 이해가 되네요. 파일의 행을 모두 가로 행으로 시각화합니다 \n. tac이 행의 순서를 반대로 바꿉니다. 이 경우 \n파일의 중간에서 제거가 종료 행이 다음 행에 가입되어 있지만, 마지막 줄의 경우에 가입 할 다음 행이 없습니다.
Shining

답변:


15

GS2, 3 바이트

* +

3 바이트는 순서대로 분할 선, 반전 및 결합선입니다.


9

펄, 11 바이트

$\=$_.$\}{

정확하게 동작합니다 tac. 이 코드에는 -p스위치 가 필요 하며 1 바이트로 계산했습니다.

시운전

$ echo -en 'a\nb' | perl -pe'$\=$_.$\}{' | xxd -g 1
0000000: 62 61 0a                                         ba.
$ echo -en 'a\nb\n' | perl -pe'$\=$_.$\}{' | xxd -g 1
0000000: 62 0a 61 0a                                      b.a.

작동 원리

여기 에 설명 된 것처럼 -p스위치는 기본적으로 while (<>) { ... ; print }프로그램을 둘러싼 것이므로 소스 코드는 다음과 같습니다.

 while(<>)
 {
   $\ = $_ . $\
 }
 print

각 입력 줄에 대해 현재 줄 ( $_)을 앞에 추가하고 $\(처음에는 정의되지 않음) 후자를 결과로 업데이트합니다.

모든 행이 처리 된 후 print로컬 변수 값 $_(이 범위에서 정의되지 않음)과 출력 레코드 구분 기호 ( $\)가 인쇄됩니다.


이것이 어떻게 작동하는지 설명해 주시겠습니까?
xebtl

2
@xebtl 이블 리. -p스위치를 추가하면 코드가 시작 while(<>){하고 끝나는 루프로 코드가 래핑되므로 } continue { print }수정만으로 입력을 필터링 할 수 있습니다 $_. $\=$_.$\각 입력 행을 출력 레코드 터미네이터 앞에 추가 }{하고 펄 제공 while블록을 조기에 종료하므로 continue블록이 더 이상 연결되지 않습니다. 따라서 모든 입력 라인이 $\역순 으로 추가 된 후 continue { print }결국에는 "아무것도"( $_입력이 끝난 후 정의 되지 않음)를 인쇄 하지만 종료자는으로 종료됩니다 $\.
홉스

@xebtl grr, 주석의 코드 형식은 백 슬래시와 백틱이 서로 가까이있는 곳에서 약간 깨진 것처럼 보입니다. 아마도 내가 말하려는 것을 추측 할 수 있습니다.
홉스

1
@primo 첫 번째 예는이 경우에 어떤 일이 발생하는지 보여줍니다. 결과는 이상하지만, 전술과 똑같습니다.
Dennis

1
@Dennis 페이지 18 ff 이 책
msh210

8

Pyth, 4 바이트

j_.z

.z는 입력으로 행으로 구분 된 입력이며, _반대로 입력 j하고 문자를 기준으로 결합합니다 \n. 기본적으로는입니다 .



7

망막 , 7 바이트

!rm`.*$

단일 정규 표현식으로 Retina는 일치 모드에서 실행됩니다. 이것은 일반적으로 일치 횟수 !를 인쇄하지만 실제 일치를 대신 인쇄하도록 구성합니다 (줄 바꿈으로 구분).

실제 정규식은 단지 .*$입니다. 줄 바꿈을 제외한 모든 문자와 일치 할 수 .*있으므로 모든 행과 일치합니다 (잠재적으로 비어 있음) .. 나는 $잠시 후에 갈 것이다 .

일치 항목을 반대로 인쇄하려면 어떻게해야합니까? .NET의 오른쪽에서 왼쪽으로 일치하는 모드를 사용하여 r. 이것은 정규식 엔진이 일치하는 항목을 찾을 때 문자열의 끝에서 시작하여 뒤로 작동한다는 것을 의미합니다.

마지막으로,이 m차종 $일치 a의 끝 라인 대신 문자열의 끝을. 왜 우리는 그것을 필요로합니까? 문제는 .*불필요한 일치 를 생성 한다는 것 입니다. 정규식 대체를 고려하십시오

s/a*/$0x/

입력에 적용됩니다 baaababaa. 당신은 이것이 산출 할 것이라고 생각할 것입니다 baaaxbaxbaax, 그러나 그것은 실제로 당신에게 줄 것 baaaxxbaxxbaaxx입니다. 왜? aaa엔진의 커서를 일치 시킨 후 a와 사이에 있기 때문 b입니다. 이제 더 이상 일치하지 않을 수 a의, 그러나 a*또한 빈 문자열로 만족된다. 즉, 매 경기마다 빈 경기가 다시 발생합니다.

빈 줄이 추가되기 때문에 여기서는 원하지 않습니다. 따라서 일치하는 끝을 포함하도록 요구 하여 관련없는 일치 항목 ( 오른쪽에서 왼쪽 모드로 인해 줄 의 시작 부분 에 있음) 을 버립니다. 라인.


6

하스켈, 34 바이트

main=interact$concat.reverse.lines

[편집하다]

로 교체 unlines하여 1 바이트를 저장 했습니다 concat.


4

CJam, 7 바이트

qN/W%N*

stdin을 읽고 stdout으로 인쇄합니다.

설명:

q       Get input.
N/      Split at newlines.
W%      Reverse list.
N*      Join with newlines.


4

Befunge-93, 17 바이트

~:1+!#v_
>:#,_@>$

여기서 멋진 것은 없습니다. 스택에 모든 것을 넣은 다음 꺼내십시오.


4

퓨어 배쉬 (외부 유틸리티 없음), 56

mapfile a
for((i=${#a[@]};i--;));{
printf %s "${a[i]}"
}

이것은 Dennis의 의견tac 에서 묻는 것처럼 정확한 에뮬레이션 을 수행하는 몇 가지 답변 중 하나입니다 .

$ echo -en 'a\nb' | ./tacemu.sh | xxd -g 1
0000000: 62 61 0a                                         ba.
$ echo -en 'a\nb\n' | ./tacemu.sh | xxd -g 1
0000000: 62 0a 61 0a                                      b.a.
$ 



4

자바 스크립트 (SpiderMonkey Shell), 38 바이트

[...read(readline())].reverse().join``

매우 간단


read() 파일을 읽습니다

readline() STDIN에서 문자열을 읽습니다.

[...str]str 을 문자 배열로 나눕니다.

reverse() 배열을 반전시킵니다

join`` 배열을 문자열로 축소합니다


4

파이썬 2, 52 바이트

import sys;print''.join(sys.stdin.readlines()[::-1])

1
input ()이 stdin에서 한 줄을 읽지 않습니까?
Lynn

@Mauris 편집을
베타 붕괴

무엇에 대해 import sys;print sys.stdin.read()[::-1]?
Dieter

@dieter 각 캐릭터를 뒤집는 도전은 단지 줄을 뒤집을 것을 요구합니다.
Beta Decay

ok my
bad-

4

C #, 179171 바이트

using B=System.Console;class A{static void Main(){var a=new System.Collections.Stack();string b;while((b=B.ReadLine())!=null)a.Push(b);foreach(var c in a)B.WriteLine(c);}}

행을 읽고 스택에 넣은 다음 뒤로 씁니다. 나는 이것을 위해 Mathematica를 사용할 것이지만 EOF에 대한 의미는 없습니다.


3

sed, 9 바이트

1!G;h;$!d

공감대를 원치 않았습니다. 이것은 유명한 sed one-liner입니다.


10
자신의 작품이 아닌 경우 답변 커뮤니티 위키를 작성하는 것이 좋습니다.
lirtosiast

3

펄, 16 바이트

print reverse<>

@Dennis 죄송합니다, 이제 되돌 렸습니다.
steve

3

파워 쉘, 41 바이트

$a=$args|%{gc $_};[array]::Reverse($a);$a

파일의 내용을 한 줄씩 저장하고 a, 뒤집고 a마지막으로 인쇄합니다.



3

해 학적 인 , 6 바이트

ln<-uN

ln원시 출력을 위해 행을 분할하고 <-반전하고 uN결합하며 형식을 지정합니다.


3

배쉬, 48 43 자

( Digital TraumaBash 답변에서 영감을 얻었 습니다. 아이디어에 대한 공감대가 그에게 가야합니다.)

mapfile -c1 -C's=$2$s;set'
printf %s "$2$s"

샘플 실행 :

bash-4.3$ echo -en 'a\nb' | bash tac.sh | xxd -g 1
0000000: 62 61 0a                                         ba.

bash-4.3$ echo -en 'a\nb\n' | bash tac.sh | xxd -g 1
0000000: 62 0a 61 0a                                      b.a.

나는 당신이 mapfile -c1 -Cf대신 할 수 있다고 생각합니다 mapfile -c1 -Cf a.
Digital Trauma

옳은. 나는 또한 그 동안 그것을 발견했고, 그 까다로운 것을 -C먼저 시도했습니다 .
manatwork

3

GNU Awk, 27 자

( Ed MortonGNU Awk 답변에서 영감을 얻었습니다 . CW는 솔루션을 탈취하려고하지 않았습니다.)

{s=$0RT s}END{printf"%s",s}

RT→ 변경 RS하면 이식 가능한 표준 Awk가되지만 최종 줄 바꿈이없는 상태를 유지하는 기능은 느슨해집니다.

샘플 실행 :

bash-4.3$ echo -en 'a\nb' | awk '{s=$0RT s}END{printf"%s",s}' | xxd -g 1
0000000: 62 61 0a                                         ba.

bash-4.3$ echo -en 'a\nb\n' | awk '{s=$0RT s}END{printf"%s",s}' | xxd -g 1
0000000: 62 0a 61 0a                                      b.a.

"% s"를 제거 할 수 있습니다
ninjalj

@ninjalj (입력에 "%"가 포함되지 않는다고 가정 할 수있는 경우에만).
manatwork

3

스노볼, 42 바이트

S S =INPUT CHAR(10) S :S(S)
 OUTPUT =S
END

2

Gema, 25 자

*\n=@set{s;$0${s;}}
\Z=$s

샘플 실행 :

bash-4.3$ echo -en 'a\nb' | gema '*\n=@set{s;$0${s;}};\Z=$s'
ba

bash-4.3$ echo -en 'a\nb\n' | gema '*\n=@set{s;$0${s;}};\Z=$s'
b
a


2

sed, 7 바이트

G;h;$!d

이것은 나를 위해 작동하며 다른 곳에서 가장 짧은 솔루션이지만 실제로 이유를 찾고 싶지 않습니다. 나는 이것을 발견 할 때까지 유명한 9 바이트 트릭으로 엉망이되었습니다. G첫 줄을 밟아도 아무것도 안될 것 같아요 ?


2
실제로는 무언가를 수행합니다. 코드는 출력 끝에 줄 바꿈을 추가로 생성합니다. ( G개행 공간과 보유 공간의 내용을 패턴 공간에 추가합니다. 빈 보유 공간의 내용을 추가하는 것은 실제로 무해하지만, 개행은 여전히 ​​추가됩니다.)
manatwork

2

자바 스크립트 (Node.js), 91 바이트

console.log(require('fs').readFileSync(process.argv[2])+"".split(d="\n").reverse().join(d))

console.log((require('fs').readFileSync(process.argv[2])+"").split(d="\n").reverse().join(d))(92 바이트) 을 의미 했습니까 ? 현재 코드는 줄을 바꾸지 않습니다.
칫솔

2

배쉬 + 공통 유틸리티, 25

tr \\n ^G|rev|tr ^G \\n|rev

여기는 ^G리터럴입니다BEL 문자. 입력이 인쇄 가능한 ASCII 형식이라고 가정합니다.

이렇게 tr하면 개행을 BEL로 교체하여 전체 입력을 한 줄로 변형 한 다음 rev해당 줄을 tr병합 한 다음 rev다시 여러 줄로 변형 한 다음 각 줄을 다시 수정하여 원하는 출력을 얻을 수 있습니다.


2

MATLAB, 44

@(x) strjoin(fliplr(strsplit(x,'\n')),'\n');

문자열을 새 줄로 나누고 결과 배열을 뒤집은 다음 새 줄 문자와 다시 결합합니다.


2

줄리아, 65 바이트

open(s->print(join(reverse([l for l=readlines(s)]),"")),ARGS[1])

파일을 명령 행 인수로 사용하여 해당 행을 역순으로 인쇄합니다. 후행 줄 바꿈이 달리 앞쪽으로 이동tac 은 합법적 인와 .

언 골프 드 :

function p(s::Stream)
    # Create a vector of the lines of the input stream
    L = [l for l in readlines(s)]

    # Reverse the vector and join it back into a string
    j = join(reverse(L), "")

    # Print the string to STDOUT
    print(j)
end

# Open the file specified in the first command line argument
# and apply the function p to its contents
open(p, ARGS[1])

2

, 3 + 2 = 5 바이트

rn플래그를 사용합니다 . stdin에서 읽습니다.

RVg

r플래그의 행 목록으로 저장 표준 입력을 판독한다 g(커맨드 라인 AR 목록 통상적 인 g 들). 그런 다음 해당 목록을 반대로 바꾸면 자동 인쇄됩니다. 이 n플래그는 목록을 개행 문자와 함께 구분자로 출력합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.