스크립트 입력에 지정된 순서에 따라 파일의 각 레코드 필드를 재정렬합니다.

스크립트 입력에 지정된 순서에 따라 파일의 각 레코드 필드를 재정렬합니다.

여러 레코드가 포함된 파일이 있는데 각 레코드에는 여러 필드가 있습니다. 파일의 내용은 다음과 같습니다.

# cat inputfile

name: AAA
age:  38
city: C1
state: S1

age: 29
city: C2
name: BBBbbbB
state: S2

state: S3
age: 21
city: C3
name: ccccccC 

쉘 스크립트의 매개변수에 지정된 순서대로 각 레코드의 필드를 정렬하고 싶습니다.

다음과 같은 스크립트를 실행하면:

# sh sortout.sh <inputfile> name age city state

출력은 다음과 같아야 합니다.

name: AAA
age:  38
city: C1
state: S1

name: BBBbbbB
age: 29
city: C2
state: S2

name: ccccccC 
age: 21
city: C3
state: S3

답변1

단락 모드에서 작업할 때 Perl이는 Perl이 이 옵션을 사용하여 한 번에 한 단락씩 먹도록 하는 것을 의미합니다 -00.

그런 다음 현재 레코드에서 첫 번째 필드(콜론으로 구분)를 가져와 해시에 저장합니다.

$ perl -l -00ane '
    my %h = reverse /^(([^:]+):.*)$/mg;
    print $h{$_} for qw/name age city state/;
' input.file

특정 요구 사항에 따라 다음을 수행할 수 있습니다.

cat - <<\eof > code.sh
if=$1;shift
perl -ls -00ane '
  my %h = reverse /^(([^:]+):.*)$/mg;
  print $h{$_} for split /\s+/, $order;
' -- -order="$*" "$if"
eof

코드 파일을 생성한 후 실행합니다.

sh code.sh inputfile name age city state

답변2

당신은 Perl을 모르기 때문에 좀 더 장황하게 설명하겠습니다.

첫째, Perl은 입력 파일을 가져와 명령을 통해 변환하여 원하는 출력을 생성하는 Linux 유틸리티입니다.

일반적으로 Perl은 입력 파일을 한 번에 한 줄씩 확인합니다. 한 줄은 ASCII 문자 \012 (개행 문자라고도 함)로 다음 줄과 \n구분됩니다 . 하지만 이 경우에는 한 번에 한 단락씩 읽는 것이 좋습니다. Perl은 para를 어떻게 식별합니까?

-00옵션은 단락을 처리합니다. 현재 레코드 스칼라에 저장됩니다.$_

이제 레코드에는 여러 행이 포함되어야 합니다.

^....$ ^...$ ^....$ 나는 그것을 기본적으로 연속적인 선의 섬 이라고 상상합니다 . 섬은 \n으로 구분됩니다.

사용된 Perl 옵션:

-l 이는 두 가지 작업을 수행합니다. 현재 레코드 $_에서 입력 레코드 구분 기호를 제거하고 인쇄할 때 다시 넣습니다. $/ = $\ = "\n"

-s그러면 기본 명령줄 스위치 구문 분석이 활성화됩니다. 이를 통해 명령줄 자체에서 변수가 인쇄되는 순서를 지정할 수 있습니다.

-00예 IRS 구분 기호는 단락 모드 = 빈 문자열로 설정됩니다. 그러면 입력 데이터에서 한 번에 한 단락씩 추출되어 $_for의 각 반복마다 저장됩니다.

-n이렇게 하면 파일 주위에 루프가 생깁니다. 즉, 입력 파일(실제로는 파일 핸들이지만 이는 우리 수준에서는 중요하지 않음)에서 읽게 되지만 변환이 모두 현재 레코드에 적용되면 읽히지 않습니다. 마지막에 인쇄됩니다. 이 작업은 명시적으로 수행해야 합니다.

-e이 옵션은 다음에 나오는 내용이 현재 레코드에 적용될 유효한 Perl 코드임을 Perl에게 알려줍니다.

--=> Perl 명령줄 옵션의 끝, 스위치(대시로 시작), 파일 순입니다. 파일 이름이 대시로 시작될 가능성이 있는 경우 ./로 시작하고 전체 또는 상대 경로를 제공하거나 --스위치 끝을 나타내는 다른 경로를 입력하는 것이 좋습니다 .

#

이제 algorithm 그 부분은 다음과 같습니다.

my %h = reverse /^(([^:]+):. *)$/mg;

% Perl에서 해시 또는 연관 배열은 이름 앞의 백분율로 식별됩니다. 따라서 우리의 경우에는 해시를 작성 %h 하고 그 앞에 a를 배치합니다 my. 즉, 다음 레코드를 읽을 때마다 해시가 어휘적이며 if 범위를 종료한다는 의미입니다. 이는 각 레코드에 대해 완전히 새로운 해시가 생성된다는 것을 의미합니다.

이 표현은 무엇을 /..../mg의미하나요? 첫째, 모든 정규 표현식은 항상 if 연산자를 통해 일부 스칼라 변수 또는 표현식과 연결됩니다 =~. 하지만 여기서는 하나도 보이지 않습니다. $_현재 레코드를 의미하는 변수에 암시적으로 바인딩됩니다 .

계속됩니다- -

관련 정보